From d2c35ec62a595dc02542edae920b6a63dbb57446 Mon Sep 17 00:00:00 2001 From: Tristan Van Berkom Date: Mon, 12 Apr 2010 22:21:46 -0400 Subject: [PATCH] Mega commit to change ->get_desired_size() for ->get_desired_width/height(). This commit changes gtk_extended_layout_get_desired_size() for per dimension variants. Furthermore this commit reverts the actions done in size-groups for now as it needs a different approach. The natural width/height parameters added to aux_info have been changed for a per width cache for heights and a per height cache for widths. gtk-demo is still working, currently sizegroups are not taken into account as mentioned above - size groups need to be alerted both when the widths and heights are updated independantly and then that information needs to repropagate also to other extended layout implementors. --- gtk/gtk.symbols | 11 +- gtk/gtkalignment.c | 74 +++++--- gtk/gtkbin.c | 21 ++- gtk/gtkbox.c | 199 ++++++++++---------- gtk/gtkbutton.c | 88 ++++++--- gtk/gtkcellrenderer.c | 102 ++++++++-- gtk/gtkcellrenderertext.c | 73 ++++++-- gtk/gtkcellview.c | 182 ++++++++++++------ gtk/gtkcellview.h | 10 +- gtk/gtkcombobox.c | 61 +++++- gtk/gtkcontainer.c | 3 + gtk/gtkextendedcell.c | 136 +++++++++++++- gtk/gtkextendedcell.h | 46 ++++- gtk/gtkextendedlayout.c | 381 ++++++++++++++++++++++++++++++++++---- gtk/gtkextendedlayout.h | 30 +-- gtk/gtklabel.c | 103 ++++++----- gtk/gtkprivate.h | 59 +++--- gtk/gtkscrolledwindow.c | 112 ++++++----- gtk/gtksizegroup.c | 279 ++++++++-------------------- gtk/gtksizegroup.h | 5 +- gtk/gtksocket.c | 76 +++++--- gtk/gtktreeview.c | 66 +++++-- gtk/gtktreeviewcolumn.c | 12 +- gtk/gtkviewport.c | 68 +++++-- gtk/gtkwidget.c | 89 ++++----- gtk/gtkwidget.h | 18 +- gtk/gtkwindow.c | 45 +---- 27 files changed, 1558 insertions(+), 791 deletions(-) diff --git a/gtk/gtk.symbols b/gtk/gtk.symbols index 97838cd003..9c145397f9 100644 --- a/gtk/gtk.symbols +++ b/gtk/gtk.symbols @@ -719,7 +719,8 @@ gtk_cell_renderer_toggle_set_radio #ifndef GTK_DISABLE_DEPRECATED gtk_cell_view_get_cell_renderers #endif -gtk_cell_view_get_desired_size_of_row +gtk_cell_view_get_desired_height_of_row +gtk_cell_view_get_desired_width_of_row gtk_cell_view_get_displayed_row gtk_cell_view_get_model gtk_cell_view_get_size_of_row @@ -1507,14 +1508,18 @@ gtk_expander_set_use_underline #if IN_HEADER(__GTK_EXTENDED_CELL_H__) #if IN_FILE(__GTK_EXTENDED_CELL_C__) gtk_extended_cell_get_type G_GNUC_CONST -gtk_extended_cell_get_desired_size +gtk_extended_cell_get_desired_height +gtk_extended_cell_get_desired_width +gtk_extended_cell_get_height_for_width +gtk_extended_cell_get_width_for_height #endif #endif #if IN_HEADER(__GTK_EXTENDED_LAYOUT_H__) #if IN_FILE(__GTK_EXTENDED_LAYOUT_C__) gtk_extended_layout_get_type G_GNUC_CONST -gtk_extended_layout_get_desired_size +gtk_extended_layout_get_desired_height +gtk_extended_layout_get_desired_width gtk_extended_layout_get_height_for_width gtk_extended_layout_get_width_for_height gtk_extended_layout_is_height_for_width diff --git a/gtk/gtkalignment.c b/gtk/gtkalignment.c index 55a210d705..7e879ca056 100644 --- a/gtk/gtkalignment.c +++ b/gtk/gtkalignment.c @@ -66,10 +66,13 @@ static void gtk_alignment_get_property (GObject *object, GValue *value, GParamSpec *pspec); -static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface); -static void gtk_alignment_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_alignment_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_alignment_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); G_DEFINE_TYPE_WITH_CODE (GtkAlignment, gtk_alignment, GTK_TYPE_BIN, G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT, @@ -484,42 +487,69 @@ gtk_alignment_size_allocate (GtkWidget *widget, static void gtk_alignment_extended_layout_init (GtkExtendedLayoutIface *iface) { - iface->get_desired_size = gtk_alignment_get_desired_size; + iface->get_desired_width = gtk_alignment_get_desired_width; + iface->get_desired_height = gtk_alignment_get_desired_height; } static void gtk_alignment_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkWidget *child; GtkAlignmentPrivate *priv; + gint minimum, natural; priv = GTK_ALIGNMENT_GET_PRIVATE (layout); - minimum_size->width = GTK_CONTAINER (layout)->border_width * 2; - minimum_size->height = GTK_CONTAINER (layout)->border_width * 2; - - *natural_size = *minimum_size; + natural = minimum = GTK_CONTAINER (layout)->border_width * 2; if ((child = gtk_bin_get_child (GTK_BIN (layout))) && gtk_widget_get_visible (child)) { - GtkRequisition child_min, child_nat; + gint child_min, child_nat; /* Request extra space for the padding: */ - minimum_size->width += (priv->padding_left + priv->padding_right); - minimum_size->height += (priv->padding_top + priv->padding_bottom); - - *natural_size = *minimum_size; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + minimum += (priv->padding_left + priv->padding_right); + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), + &child_min, &child_nat); + } + else + { + minimum += (priv->padding_top + priv->padding_bottom); + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), + &child_min, &child_nat); + } - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child), - &child_min, &child_nat); + natural = minimum; - minimum_size->width += child_min.width; - minimum_size->height += child_min.height; - natural_size->width += child_nat.width; - natural_size->height += child_nat.height; + minimum += child_min; + natural += child_nat; } + + if (minimum_size) + *minimum_size = minimum; + + if (natural_size) + *natural_size = natural; +} + +static void +gtk_alignment_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_alignment_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_alignment_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_alignment_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } /** diff --git a/gtk/gtkbin.c b/gtk/gtkbin.c index d2a052caad..f8c9b7522d 100644 --- a/gtk/gtkbin.c +++ b/gtk/gtkbin.c @@ -168,17 +168,16 @@ get_child_padding_delta (GtkBin *bin, gint *delta_h, gint *delta_v) { - GtkRequisition min_req, child_min; + gint hmin, vmin, child_hmin, child_vmin; - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin), - &min_req, NULL); + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (bin), &hmin, NULL); + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin), &vmin, NULL); - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child), - &child_min, NULL); + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (bin->child), &child_hmin, NULL); + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin->child), &child_vmin, NULL); - - *delta_h = min_req.width - child_min.width; - *delta_v = min_req.height - child_min.height; + *delta_h = hmin - child_hmin; + *delta_v = vmin - child_vmin; } static void @@ -205,7 +204,8 @@ gtk_bin_get_width_for_height (GtkExtendedLayout *layout, *natural_width = child_nat + hdelta; } else - parent_extended_layout_iface->get_height_for_width (layout, height, minimum_width, natural_width); + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width); +/* parent_extended_layout_iface->get_height_for_width (layout, height, minimum_width, natural_width); */ } static void @@ -232,7 +232,8 @@ gtk_bin_get_height_for_width (GtkExtendedLayout *layout, *natural_height = child_nat + vdelta; } else - parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height); + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height); +/* parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height); */ } diff --git a/gtk/gtkbox.c b/gtk/gtkbox.c index 27c4de118c..0f2c7aeb2e 100644 --- a/gtk/gtkbox.c +++ b/gtk/gtkbox.c @@ -109,19 +109,22 @@ static void gtk_box_get_child_property (GtkContainer *container, static GType gtk_box_child_type (GtkContainer *container); -static void gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface); -static void gtk_box_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); -static gboolean gtk_box_is_height_for_width (GtkExtendedLayout *layout); -static void gtk_box_get_width_for_height (GtkExtendedLayout *layout, - gint height, - gint *minimum_width, - gint *natural_width); -static void gtk_box_get_height_for_width (GtkExtendedLayout *layout, - gint width, - gint *minimum_height, - gint *natural_height); +static void gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface); +static gboolean gtk_box_is_height_for_width (GtkExtendedLayout *layout); +static void gtk_box_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_box_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_box_get_width_for_height (GtkExtendedLayout *layout, + gint height, + gint *minimum_width, + gint *natural_width); +static void gtk_box_get_height_for_width (GtkExtendedLayout *layout, + gint width, + gint *minimum_height, + gint *natural_height); static GtkExtendedLayoutIface *parent_extended_layout_iface; @@ -378,8 +381,22 @@ gtk_box_size_allocate (GtkWidget *widget, /* Assert the api is working properly */ - g_assert (sizes[i].minimum_size >= 0); - g_assert (sizes[i].natural_size >= sizes[i].minimum_size); + if (sizes[i].minimum_size < 0) + g_error ("GtkBox child %s minimum %s: %d < 0 for %s %d", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].minimum_size, + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); + + if (sizes[i].natural_size < sizes[i].minimum_size) + g_error ("GtkBox child %s natural %s: %d < minimum %d for %s %d", + gtk_widget_get_name (GTK_WIDGET (child->widget)), + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "width" : "height", + sizes[i].natural_size, + sizes[i].minimum_size, + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? "height" : "width", + (private->orientation == GTK_ORIENTATION_HORIZONTAL) ? allocation->height : allocation->width); size -= sizes[i].minimum_size; size -= child->padding * 2; @@ -749,7 +766,8 @@ gtk_box_extended_layout_init (GtkExtendedLayoutIface *iface) parent_extended_layout_iface = g_type_interface_peek_parent (iface); iface->is_height_for_width = gtk_box_is_height_for_width; - iface->get_desired_size = gtk_box_get_desired_size; + iface->get_desired_width = gtk_box_get_desired_width; + iface->get_desired_height = gtk_box_get_desired_height; iface->get_height_for_width = gtk_box_get_height_for_width; iface->get_width_for_height = gtk_box_get_width_for_height; } @@ -763,121 +781,106 @@ gtk_box_is_height_for_width (GtkExtendedLayout *layout) } static void -gtk_box_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_box_get_desired_size (GtkExtendedLayout *layout, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkBox *box; GtkBoxPrivate *private; GList *children; gint nvis_children; gint border_width; + gint minimum, natural; box = GTK_BOX (layout); private = GTK_BOX_GET_PRIVATE (box); border_width = GTK_CONTAINER (box)->border_width; - minimum_size->width = minimum_size->height = 0; - natural_size->width = natural_size->height = 0; + minimum = natural = 0; nvis_children = 0; - children = box->children; - while (children) - { - GtkBoxChild *child; - child = children->data; - children = children->next; + for (children = box->children; children; children = children->next) + { + GtkBoxChild *child = children->data; if (gtk_widget_get_visible (child->widget)) { - GtkRequisition child_minimum_size; - GtkRequisition child_natural_size; - - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child->widget), - &child_minimum_size, - &child_natural_size); - - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (box->homogeneous) - { - gint width; + gint child_minimum, child_natural; - width = child_minimum_size.width + child->padding * 2; - minimum_size->width = MAX (minimum_size->width, width); - - width = child_natural_size.width + child->padding * 2; - natural_size->width = MAX (natural_size->width, width); - } - else - { - minimum_size->width += child_minimum_size.width + child->padding * 2; - natural_size->width += child_natural_size.width + child->padding * 2; - } + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child->widget), + &child_minimum, &child_natural); + else + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child->widget), + &child_minimum, &child_natural); - minimum_size->height = MAX (minimum_size->height, child_minimum_size.height); - natural_size->height = MAX (natural_size->height, child_natural_size.height); - } - else - { + if (private->orientation == orientation) + { if (box->homogeneous) { - gint height; + gint largest; - height = child_minimum_size.height + child->padding * 2; - minimum_size->height = MAX (minimum_size->height, height); + largest = child_minimum + child->padding * 2; + minimum = MAX (minimum, largest); - height = child_natural_size.height + child->padding * 2; - natural_size->height = MAX (natural_size->height, height); + largest = child_natural + child->padding * 2; + natural = MAX (natural, largest); } else { - minimum_size->height += child_minimum_size.height + child->padding * 2; - natural_size->height += child_natural_size.height + child->padding * 2; + minimum += child_minimum + child->padding * 2; + natural += child_natural + child->padding * 2; } - - minimum_size->width = MAX (minimum_size->width, child_minimum_size.width); - natural_size->width = MAX (natural_size->width, child_natural_size.width); - } - + } + else + { + /* The biggest mins and naturals in the opposing orientation */ + minimum = MAX (minimum, child_minimum); + natural = MAX (natural, child_natural); + } nvis_children += 1; } } - if (nvis_children > 0) + + if (nvis_children > 0 && private->orientation == orientation) { - if (private->orientation == GTK_ORIENTATION_HORIZONTAL) - { - if (box->homogeneous) - { - minimum_size->width *= nvis_children; - natural_size->width *= nvis_children; - } + if (box->homogeneous) + { + minimum *= nvis_children; + natural *= nvis_children; + } + minimum += (nvis_children - 1) * box->spacing; + natural += (nvis_children - 1) * box->spacing; + } - minimum_size->width += (nvis_children - 1) * box->spacing; - natural_size->width += (nvis_children - 1) * box->spacing; - } - else - { - if (box->homogeneous) - { - minimum_size->height *= nvis_children; - natural_size->height *= nvis_children; - } + minimum += border_width * 2; + natural += border_width * 2; - minimum_size->height += (nvis_children - 1) * box->spacing; - natural_size->height += (nvis_children - 1) * box->spacing; - } - } + if (minimum_size) + *minimum_size = minimum; - minimum_size->width += border_width * 2; - minimum_size->height += border_width * 2; + if (natural_size) + *natural_size = natural; +} - natural_size->width += border_width * 2; - natural_size->height += border_width * 2; +static void +gtk_box_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_box_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); } +static void +gtk_box_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_box_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); +} /** * size_fits_for_dimension: @@ -1101,10 +1104,10 @@ gtk_box_get_width_for_height (GtkExtendedLayout *layout, if (private->orientation == GTK_ORIENTATION_VERTICAL) { #if 0 - gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width); + gtk_box_compute_size_for_opposing_orientation (box, height, minimum_width, natural_width); #else - /* Have the base class return the values previously computed by get_desired_size() */ - parent_extended_layout_iface->get_width_for_height (layout, height, minimum_width, natural_width); + /* Return the defaults instead of calculating in the opposing direction */ + gtk_extended_layout_get_desired_width (layout, minimum_width, natural_width); #endif } else @@ -1125,8 +1128,8 @@ gtk_box_get_height_for_width (GtkExtendedLayout *layout, #if 0 gtk_box_compute_size_for_opposing_orientation (box, width, minimum_height, natural_height); #else - /* Have the base class return the values previously computed by get_desired_size() */ - parent_extended_layout_iface->get_height_for_width (layout, width, minimum_height, natural_height); + /* Return the defaults instead of calculating in the opposing direction */ + gtk_extended_layout_get_desired_height (layout, minimum_height, natural_height); #endif } else diff --git a/gtk/gtkbutton.c b/gtk/gtkbutton.c index 7391de389f..37367b3fb3 100644 --- a/gtk/gtkbutton.c +++ b/gtk/gtkbutton.c @@ -159,9 +159,12 @@ static void gtk_button_set_use_action_appearance (GtkButton *button, gboolean use_appearance); static void gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface); -static void gtk_button_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +static void gtk_button_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_button_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); static guint button_signals[LAST_SIGNAL] = { 0 }; @@ -1769,13 +1772,15 @@ gtk_button_finish_activate (GtkButton *button, static void gtk_button_extended_layout_init (GtkExtendedLayoutIface *iface) { - iface->get_desired_size = gtk_button_get_desired_size; + iface->get_desired_width = gtk_button_get_desired_width; + iface->get_desired_height = gtk_button_get_desired_height; } static void gtk_button_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkButton *button = GTK_BUTTON (layout); GtkWidget *child; @@ -1783,47 +1788,74 @@ gtk_button_get_desired_size (GtkExtendedLayout *layout, GtkBorder inner_border; gint focus_width; gint focus_pad; + gint minimum, natural; gtk_button_get_props (button, &default_border, NULL, &inner_border, NULL); gtk_widget_style_get (GTK_WIDGET (layout), "focus-line-width", &focus_width, "focus-padding", &focus_pad, NULL); - - minimum_size->width = ((GTK_CONTAINER (layout)->border_width + - GTK_WIDGET (layout)->style->xthickness) * 2 + - inner_border.left + inner_border.right); - minimum_size->height = ((GTK_CONTAINER (layout)->border_width + - GTK_WIDGET (layout)->style->ythickness) * 2 + - inner_border.top + inner_border.bottom); - - if (gtk_widget_get_can_default (GTK_WIDGET (layout))) + + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - minimum_size->width += default_border.left + default_border.right; - minimum_size->height += default_border.top + default_border.bottom; + minimum = ((GTK_CONTAINER (layout)->border_width + + GTK_WIDGET (layout)->style->xthickness) * 2 + + inner_border.left + inner_border.right); + + if (gtk_widget_get_can_default (GTK_WIDGET (layout))) + minimum += default_border.left + default_border.right; } + else + { + minimum = ((GTK_CONTAINER (layout)->border_width + + GTK_WIDGET (layout)->style->ythickness) * 2 + + inner_border.top + inner_border.bottom); - minimum_size->width += 2 * (focus_width + focus_pad); - minimum_size->height += 2 * (focus_width + focus_pad); + if (gtk_widget_get_can_default (GTK_WIDGET (layout))) + minimum += default_border.top + default_border.bottom; + } - *natural_size = *minimum_size; + minimum += 2 * (focus_width + focus_pad); + natural = minimum; if ((child = gtk_bin_get_child (GTK_BIN (button))) && gtk_widget_get_visible (child)) { - GtkRequisition child_min; - GtkRequisition child_nat; + gint child_min, child_nat; - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child), - &child_min, &child_nat); + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), + &child_min, &child_nat); + else + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), + &child_min, &child_nat); - minimum_size->width += child_min.width; - minimum_size->height += child_min.height; - natural_size->width += child_nat.width; - natural_size->height += child_nat.height; + minimum += child_min; + natural += child_nat; } + + if (minimum_size) + *minimum_size = minimum; + + if (natural_size) + *natural_size = natural; } +static void +gtk_button_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_button_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_button_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_button_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); +} /** * gtk_button_set_label: diff --git a/gtk/gtkcellrenderer.c b/gtk/gtkcellrenderer.c index eec6a43282..03d62a463e 100644 --- a/gtk/gtkcellrenderer.c +++ b/gtk/gtkcellrenderer.c @@ -39,7 +39,27 @@ static void gtk_cell_renderer_set_property (GObject *object, static void set_cell_bg_color (GtkCellRenderer *cell, GdkColor *color); -static void gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface); +/* Fallback GtkExtendedCell implementation to use remaining ->get_size() implementations */ +static void gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface); +static void gtk_cell_renderer_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +static void gtk_cell_renderer_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +static void gtk_cell_renderer_get_height_for_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height); +static void gtk_cell_renderer_get_width_for_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width); + #define GTK_CELL_RENDERER_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), GTK_TYPE_CELL_RENDERER, GtkCellRendererPrivate)) @@ -1036,15 +1056,26 @@ gtk_cell_renderer_stop_editing (GtkCellRenderer *cell, } } +static void +gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface) +{ + iface->get_desired_width = gtk_cell_renderer_get_desired_width; + iface->get_desired_height = gtk_cell_renderer_get_desired_height; + + iface->get_width_for_height = gtk_cell_renderer_get_width_for_height; + iface->get_height_for_width = gtk_cell_renderer_get_height_for_width; +} static void -gtk_cell_renderer_extended_cell_get_desired_size (GtkExtendedCell *cell, - GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_cell_renderer_get_desired_size (GtkExtendedCell *cell, + GtkWidget *widget, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkRequisition min_req; + /* Fallback on the old API to get the size. */ if (GTK_CELL_RENDERER_GET_CLASS (cell)->get_size) gtk_cell_renderer_get_size (GTK_CELL_RENDERER (cell), widget, NULL, NULL, NULL, &min_req.width, &min_req.height); @@ -1054,24 +1085,67 @@ gtk_cell_renderer_extended_cell_get_desired_size (GtkExtendedCell *cell, min_req.height = 0; } - if (minimum_size) + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - minimum_size->width = min_req.width; - minimum_size->height = min_req.height; - } + if (minimum_size) + *minimum_size = min_req.width; - if (natural_size) + if (natural_size) + *natural_size = min_req.width; + } + else { - natural_size->width = min_req.width; - natural_size->height = min_req.height; + if (minimum_size) + *minimum_size = min_req.height; + + if (natural_size) + *natural_size = min_req.height; } } static void -gtk_cell_renderer_extended_cell_init (GtkExtendedCellIface *iface) +gtk_cell_renderer_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + gtk_cell_renderer_get_desired_size (cell, widget, GTK_ORIENTATION_HORIZONTAL, + minimum_size, natural_size); +} + +static void +gtk_cell_renderer_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + gtk_cell_renderer_get_desired_size (cell, widget, GTK_ORIENTATION_VERTICAL, + minimum_size, natural_size); +} + + +static void +gtk_cell_renderer_get_height_for_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height) +{ + /* Fall back on the height reported from ->get_size() */ + gtk_extended_cell_get_desired_height (cell, widget, minimum_height, natural_height); +} + +static void +gtk_cell_renderer_get_width_for_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width) { - iface->get_desired_size = gtk_cell_renderer_extended_cell_get_desired_size; + /* Fall back on the width reported from ->get_size() */ + gtk_extended_cell_get_desired_width (cell, widget, minimum_width, natural_width); } + #define __GTK_CELL_RENDERER_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkcellrenderertext.c b/gtk/gtkcellrenderertext.c index e4f18408f6..859bcc1a19 100644 --- a/gtk/gtkcellrenderertext.c +++ b/gtk/gtkcellrenderertext.c @@ -62,7 +62,15 @@ static GtkCellEditable *gtk_cell_renderer_text_start_editing (GtkCellRenderer GdkRectangle *cell_area, GtkCellRendererState flags); -static void gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface); +static void gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface); +static void gtk_cell_renderer_text_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimal_size, + gint *desired_size); +static void gtk_cell_renderer_text_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimal_size, + gint *desired_size); enum { EDITED, @@ -1936,10 +1944,22 @@ gtk_cell_renderer_text_set_fixed_height_from_font (GtkCellRendererText *renderer } static void -gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell, - GtkWidget *widget, - GtkRequisition *minimal_size, - GtkRequisition *desired_size) +gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface) +{ + /* Currently cell renderers do natural widths for ellipsizing text + * but dont yet do height-for-width/width-for-height calculations for + * wordwrapping + */ + iface->get_desired_width = gtk_cell_renderer_text_get_desired_width; + iface->get_desired_height = gtk_cell_renderer_text_get_desired_height; +} + +static void +gtk_cell_renderer_text_get_desired_size (GtkExtendedCell *cell, + GtkWidget *widget, + GtkOrientation orientation, + gint *minimal_size, + gint *desired_size) { GtkCellRendererTextPrivate *priv; @@ -1947,9 +1967,14 @@ gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell, if (minimal_size) { - get_size (GTK_CELL_RENDERER (cell), - widget, NULL, NULL, NULL, NULL, - &minimal_size->width, &minimal_size->height); + if (orientation == GTK_ORIENTATION_HORIZONTAL) + get_size (GTK_CELL_RENDERER (cell), + widget, NULL, NULL, NULL, NULL, + minimal_size, NULL); + else + get_size (GTK_CELL_RENDERER (cell), + widget, NULL, NULL, NULL, NULL, + NULL, minimal_size); } if (desired_size) @@ -1959,19 +1984,39 @@ gtk_cell_renderer_text_extended_cell_get_desired_size (GtkExtendedCell *cell, ellipsize = priv->ellipsize; priv->ellipsize = PANGO_ELLIPSIZE_NONE; - get_size (GTK_CELL_RENDERER (cell), - widget, NULL, NULL, NULL, NULL, - &desired_size->width, &desired_size->height); - + if (orientation == GTK_ORIENTATION_HORIZONTAL) + get_size (GTK_CELL_RENDERER (cell), + widget, NULL, NULL, NULL, NULL, + desired_size, NULL); + else + get_size (GTK_CELL_RENDERER (cell), + widget, NULL, NULL, NULL, NULL, + NULL, desired_size); + priv->ellipsize = ellipsize; } } static void -gtk_cell_renderer_text_extended_cell_init (GtkExtendedCellIface *iface) +gtk_cell_renderer_text_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *desired_size) +{ + gtk_cell_renderer_text_get_desired_size (cell, widget, GTK_ORIENTATION_HORIZONTAL, + minimum_size, desired_size); +} + +static void +gtk_cell_renderer_text_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *desired_size) { - iface->get_desired_size = gtk_cell_renderer_text_extended_cell_get_desired_size; + gtk_cell_renderer_text_get_desired_size (cell, widget, GTK_ORIENTATION_VERTICAL, + minimum_size, desired_size); } + #define __GTK_CELL_RENDERER_TEXT_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkcellview.c b/gtk/gtkcellview.c index 123129b3a3..a85c0d7b9a 100644 --- a/gtk/gtkcellview.c +++ b/gtk/gtkcellview.c @@ -121,10 +121,13 @@ static void gtk_cell_view_buildable_custom_tag_end (GtkBuildable const gchar *tagname, gpointer *data); -static void gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface); -static void gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimal_size, - GtkRequisition *natural_size); +static void gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_cell_view_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_cell_view_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); static GtkBuildableIface *parent_buildable_iface; @@ -972,7 +975,8 @@ gtk_cell_view_get_displayed_row (GtkCellView *cell_view) * * Since: 2.6 * - * Deprecated: 3.0: Use gtk_cell_view_get_desired_size_of_row() instead. + * Deprecated: 3.0: Use gtk_cell_view_get_desired_width_of_row() and + * gtk_cell_view_get_desired_height_of_row() instead. */ gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_view, @@ -981,51 +985,97 @@ gtk_cell_view_get_size_of_row (GtkCellView *cell_view, { GtkRequisition req; - gtk_cell_view_get_desired_size_of_row (cell_view, path, requisition, &req); + g_return_val_if_fail (GTK_IS_CELL_VIEW (cell_view), FALSE); + g_return_val_if_fail (path != NULL, FALSE); + + gtk_cell_view_get_desired_width_of_row (cell_view, path, &req.width, NULL); + gtk_cell_view_get_desired_height_of_row (cell_view, path, &req.height, NULL); + + if (requisition) + *requisition = req; return TRUE; } + +static void +gtk_cell_view_get_desired_size_of_row (GtkCellView *cell_view, + GtkTreePath *path, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) +{ + GtkTreeRowReference *tmp; + + tmp = cell_view->priv->displayed_row; + cell_view->priv->displayed_row = + gtk_tree_row_reference_new (cell_view->priv->model, path); + + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_cell_view_get_desired_width (GTK_EXTENDED_LAYOUT (cell_view), minimum_size, natural_size); + else + gtk_cell_view_get_desired_height (GTK_EXTENDED_LAYOUT (cell_view), minimum_size, natural_size); + + gtk_tree_row_reference_free (cell_view->priv->displayed_row); + cell_view->priv->displayed_row = tmp; + + /* Restore active size */ + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_cell_view_get_desired_width (GTK_EXTENDED_LAYOUT (cell_view), NULL, NULL); + else + gtk_cell_view_get_desired_height (GTK_EXTENDED_LAYOUT (cell_view), NULL, NULL); +} + /** - * gtk_cell_view_get_desired_size_of_row: + * gtk_cell_view_get_desired_width_of_row: * @cell_view: a #GtkCellView * @path: a #GtkTreePath - * @minimum_size: return location for the minimum requested size - * @natural_size: return location for the desired natural size + * @minimum_size: location to store the minimum size + * @natural_size: location to store the natural size * - * Sets @minimum_size and @natural_size to the size desired by @cell_view + * Sets @minimum_size and @natural_size to the width desired by @cell_view * to display the model row pointed to by @path. * * Since: 3.0 */ void -gtk_cell_view_get_desired_size_of_row (GtkCellView *cell_view, - GtkTreePath *path, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_cell_view_get_desired_width_of_row (GtkCellView *cell_view, + GtkTreePath *path, + gint *minimum_size, + gint *natural_size) { - GtkTreeRowReference *tmp; - GtkRequisition req, nat_req; - g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); g_return_if_fail (path != NULL); g_return_if_fail (minimum_size != NULL || natural_size != NULL); - tmp = cell_view->priv->displayed_row; - cell_view->priv->displayed_row = - gtk_tree_row_reference_new (cell_view->priv->model, path); + gtk_cell_view_get_desired_size_of_row (cell_view, path, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} - gtk_cell_view_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (cell_view), - minimum_size ? minimum_size : &req, - natural_size ? natural_size : &nat_req); - gtk_tree_row_reference_free (cell_view->priv->displayed_row); - cell_view->priv->displayed_row = tmp; +/** + * gtk_cell_view_get_desired_height_of_row: + * @cell_view: a #GtkCellView + * @path: a #GtkTreePath + * @minimum_size: location to store the minimum size + * @natural_size: location to store the natural size + * + * Sets @minimum_size and @natural_size to the height desired by @cell_view + * to display the model row pointed to by @path. + * + * Since: 3.0 + */ +void +gtk_cell_view_get_desired_height_of_row (GtkCellView *cell_view, + GtkTreePath *path, + gint *minimum_size, + gint *natural_size) +{ + g_return_if_fail (GTK_IS_CELL_VIEW (cell_view)); + g_return_if_fail (path != NULL); + g_return_if_fail (minimum_size != NULL || natural_size != NULL); - /* Restore active size */ - gtk_cell_view_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (cell_view), - &req, &nat_req); + gtk_cell_view_get_desired_size_of_row (cell_view, path, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } /** @@ -1137,20 +1187,27 @@ gtk_cell_view_buildable_custom_tag_end (GtkBuildable *buildable, data); } + +static void +gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_cell_view_get_desired_width; + iface->get_desired_height = gtk_cell_view_get_desired_height; +} + static void -gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimal_size, - GtkRequisition *natural_size) +gtk_cell_view_get_desired_size (GtkExtendedLayout *layout, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GList *i; - GtkRequisition cell_min, cell_nat; + gint cell_min, cell_nat; gboolean first_cell = TRUE; GtkCellView *cellview = GTK_CELL_VIEW (layout); + gint minimum, natural; - minimal_size->width = 0; - minimal_size->height = 0; - natural_size->width = 0; - natural_size->height = 0; + minimum = natural = 0; if (cellview->priv->displayed_row) gtk_cell_view_set_cell_data (cellview); @@ -1162,34 +1219,55 @@ gtk_cell_view_extended_layout_get_desired_size (GtkExtendedLayout *layout, if (info->cell->visible) { - if (!first_cell) + if (!first_cell && orientation == GTK_ORIENTATION_HORIZONTAL) { - minimal_size->width += cellview->priv->spacing; - natural_size->width += cellview->priv->spacing; + minimum += cellview->priv->spacing; + natural += cellview->priv->spacing; } - gtk_extended_cell_get_desired_size (GTK_EXTENDED_CELL (info->cell), - GTK_WIDGET (cellview), &cell_min, &cell_nat); - - - info->requested_width = cell_min.width; - info->natural_width = cell_nat.width; - - minimal_size->width += info->requested_width; - natural_size->width += info->natural_width; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + { + gtk_extended_cell_get_desired_width (GTK_EXTENDED_CELL (info->cell), + GTK_WIDGET (cellview), &cell_min, &cell_nat); - minimal_size->height = MAX (minimal_size->height, cell_min.height); - natural_size->height = MAX (natural_size->height, cell_nat.height); + info->requested_width = cell_min; + info->natural_width = cell_nat; + minimum += info->requested_width; + natural += info->natural_width; + } + else + { + gtk_extended_cell_get_desired_height (GTK_EXTENDED_CELL (info->cell), + GTK_WIDGET (cellview), &cell_min, &cell_nat); + minimum = MAX (minimum, cell_min); + natural = MAX (natural, cell_nat); + } first_cell = FALSE; } } + + if (minimum_size) + *minimum_size = minimum; + + if (natural_size) + *natural_size = natural; } static void -gtk_cell_view_extended_layout_init (GtkExtendedLayoutIface *iface) +gtk_cell_view_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_cell_view_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_cell_view_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { - iface->get_desired_size = gtk_cell_view_extended_layout_get_desired_size; + gtk_cell_view_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } diff --git a/gtk/gtkcellview.h b/gtk/gtkcellview.h index a7ee69ebd3..3d83ad1800 100644 --- a/gtk/gtkcellview.h +++ b/gtk/gtkcellview.h @@ -72,10 +72,14 @@ gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_v gboolean gtk_cell_view_get_size_of_row (GtkCellView *cell_view, GtkTreePath *path, GtkRequisition *requisition); -void gtk_cell_view_get_desired_size_of_row (GtkCellView *cell_view, +void gtk_cell_view_get_desired_width_of_row(GtkCellView *cell_view, GtkTreePath *path, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); + gint *minimum_size, + gint *natural_size); +void gtk_cell_view_get_desired_height_of_row(GtkCellView *cell_view, + GtkTreePath *path, + gint *minimum_size, + gint *natural_size); void gtk_cell_view_set_background_color (GtkCellView *cell_view, const GdkColor *color); diff --git a/gtk/gtkcombobox.c b/gtk/gtkcombobox.c index 6b13f50ad8..60629071a8 100644 --- a/gtk/gtkcombobox.c +++ b/gtk/gtkcombobox.c @@ -467,9 +467,12 @@ static void gtk_combo_box_start_editing (GtkCellEditable *c GdkEvent *event); static void gtk_combo_box_extended_layout_init (GtkExtendedLayoutIface *iface); -static void gtk_combo_box_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +static void gtk_combo_box_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_combo_box_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); G_DEFINE_TYPE_WITH_CODE (GtkComboBox, gtk_combo_box, GTK_TYPE_BIN, @@ -5815,12 +5818,11 @@ gtk_combo_box_buildable_custom_tag_end (GtkBuildable *buildable, } - - static void gtk_combo_box_extended_layout_init (GtkExtendedLayoutIface *iface) { - iface->get_desired_size = gtk_combo_box_get_desired_size; + iface->get_desired_width = gtk_combo_box_get_desired_width; + iface->get_desired_height = gtk_combo_box_get_desired_height; } static void @@ -5844,8 +5846,13 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box) GtkRequisition req, nat_req; if (priv->cell_view) - gtk_cell_view_get_desired_size_of_row (GTK_CELL_VIEW (priv->cell_view), - path, &req, &nat_req); + { + /* XXX FIXME: Currently still not doing height-for-width in cell renderers here */ + gtk_cell_view_get_desired_width_of_row (GTK_CELL_VIEW (priv->cell_view), + path, &req.width, &nat_req.width); + gtk_cell_view_get_desired_height_of_row (GTK_CELL_VIEW (priv->cell_view), + path, &req.height, &nat_req.height); + } else { memset (&req, 0x0, sizeof (GtkRequisition)); @@ -5865,6 +5872,11 @@ gtk_combo_box_remeasure (GtkComboBox *combo_box) gtk_tree_path_free (path); } + +/* XXX TODO: Split this up into 2 orientations so as + * to properly support height-for-width/width-for-height here + * + */ static void gtk_combo_box_get_desired_size (GtkExtendedLayout *layout, GtkRequisition *minimum_size, @@ -6006,5 +6018,38 @@ gtk_combo_box_get_desired_size (GtkExtendedLayout *layout, } } +static void +gtk_combo_box_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + GtkRequisition minimum, natural; + + gtk_combo_box_get_desired_size (layout, &minimum, &natural); + + if (minimum_size) + *minimum_size = minimum.width; + + if (natural_size) + *natural_size = natural.width; +} + +static void +gtk_combo_box_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + GtkRequisition minimum, natural; + + gtk_combo_box_get_desired_size (layout, &minimum, &natural); + + if (minimum_size) + *minimum_size = minimum.height; + + if (natural_size) + *natural_size = natural.height; +} + + #define __GTK_COMBO_BOX_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkcontainer.c b/gtk/gtkcontainer.c index 6bedc86e99..2fa7c22b69 100644 --- a/gtk/gtkcontainer.c +++ b/gtk/gtkcontainer.c @@ -1370,6 +1370,9 @@ _gtk_container_queue_resize (GtkContainer *container) { GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED); GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED); + if ((resize_container && widget == GTK_WIDGET (resize_container)) || !widget->parent) break; diff --git a/gtk/gtkextendedcell.c b/gtk/gtkextendedcell.c index 3126c95fc2..67c6bacda3 100644 --- a/gtk/gtkextendedcell.c +++ b/gtk/gtkextendedcell.c @@ -27,6 +27,9 @@ #include "gtkintl.h" #include "gtkalias.h" + +#define DEBUG_EXTENDED_CELL 0 + GType gtk_extended_cell_get_type (void) { @@ -45,21 +48,21 @@ gtk_extended_cell_get_type (void) } /** - * gtk_extended_cell_get_desired_size: + * gtk_extended_cell_get_desired_width: * @cell: a #GtkExtendedCell instance * @widget: the #GtkWidget this cell will be rendering to - * @minimum_size: location for storing the minimum size, or %NULL - * @natural_size: location for storing the preferred size, or %NULL + * @minimum_size: location to store the minimum size, or %NULL + * @natural_size: location to store the natural size, or %NULL * - * Retreives a renderer's desired size. + * Retreives a renderer's desired size when rendered to @widget. * * Since: 3.0 */ void -gtk_extended_cell_get_desired_size (GtkExtendedCell *cell, - GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_extended_cell_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) { GtkExtendedCellIface *iface; @@ -68,7 +71,122 @@ gtk_extended_cell_get_desired_size (GtkExtendedCell *cell, g_return_if_fail (NULL != minimum_size || NULL != natural_size); iface = GTK_EXTENDED_CELL_GET_IFACE (cell); - iface->get_desired_size (cell, widget, minimum_size, natural_size); + iface->get_desired_width (cell, widget, minimum_size, natural_size); + +#if DEBUG_EXTENDED_CELL + g_message ("%s returning minimum width: %d and natural width: %d", + G_OBJECT_TYPE_NAME (cell), + minimum_size ? *minimum_size : 20000, + natural_size ? *natural_size : 20000); +#endif +} + + +/** + * gtk_extended_cell_get_desired_height: + * @cell: a #GtkExtendedCell instance + * @widget: the #GtkWidget this cell will be rendering to + * @minimum_size: location to store the minimum size, or %NULL + * @natural_size: location to store the natural size, or %NULL + * + * Retreives a renderer's desired size when rendered to @widget. + * + * Since: 3.0 + */ +void +gtk_extended_cell_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size) +{ + GtkExtendedCellIface *iface; + + g_return_if_fail (GTK_IS_EXTENDED_CELL (cell)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (NULL != minimum_size || NULL != natural_size); + + iface = GTK_EXTENDED_CELL_GET_IFACE (cell); + iface->get_desired_height (cell, widget, minimum_size, natural_size); + +#if DEBUG_EXTENDED_CELL + g_message ("%s returning minimum height: %d and natural height: %d", + G_OBJECT_TYPE_NAME (cell), + minimum_size ? *minimum_size : 20000, + natural_size ? *natural_size : 20000); +#endif +} + + +/** + * gtk_extended_cell_get_width_for_height: + * @cell: a #GtkExtendedCell instance + * @height: the size which is available for allocation + * @minimum_width: location for storing the minimum size, or %NULL + * @natural_width: location for storing the preferred size, or %NULL + * + * Retreives a cell renderers's desired width if it were rendered to + * @widget with the specified @height. + * + * Since: 3.0 + */ +void +gtk_extended_cell_get_width_for_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width) +{ + GtkExtendedCellIface *iface; + + g_return_if_fail (GTK_IS_EXTENDED_CELL (cell)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (NULL != minimum_width || NULL != natural_width); + + iface = GTK_EXTENDED_CELL_GET_IFACE (cell); + iface->get_width_for_height (cell, widget, height, minimum_width, natural_width); + +#if DEBUG_EXTENDED_CELL + g_message ("%s width for height: %d is minimum %d and natural: %d", + G_OBJECT_TYPE_NAME (cell), height, + minimum_width ? *minimum_width : 20000, + natural_width ? *natural_width : 20000); +#endif +} + +/** + * gtk_extended_cell_get_height_for_width: + * @cell: a #GtkExtendedCell instance + * @width: the size which is available for allocation + * @minimum_height: location for storing the minimum size, or %NULL + * @natural_height: location for storing the preferred size, or %NULL + * + * Retreives a cell renderers's desired height if it were rendered to + * @widget with the specified @width. + * + * Since: 3.0 + */ +void +gtk_extended_cell_get_height_for_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height) +{ + GtkExtendedCellIface *iface; + + g_return_if_fail (GTK_IS_EXTENDED_CELL (cell)); + g_return_if_fail (GTK_IS_WIDGET (widget)); + g_return_if_fail (NULL != minimum_height || NULL != natural_height); + + iface = GTK_EXTENDED_CELL_GET_IFACE (cell); + iface->get_height_for_width (cell, widget, width, minimum_height, natural_height); + +#if DEBUG_EXTENDED_CELL + g_message ("%s height for width: %d is minimum %d and natural: %d", + G_OBJECT_TYPE_NAME (cell), width, + minimum_height ? *minimum_height : 20000, + natural_height ? *natural_height : 20000); +#endif } #define __GTK_EXTENDED_CELL_C__ diff --git a/gtk/gtkextendedcell.h b/gtk/gtkextendedcell.h index 0313f32cf1..8bd38f7e2c 100644 --- a/gtk/gtkextendedcell.h +++ b/gtk/gtkextendedcell.h @@ -42,20 +42,46 @@ struct _GtkExtendedCellIface /* virtual table */ - void (*get_desired_size) (GtkExtendedCell *cell, - GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); + void (* get_desired_width) (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); + void (* get_desired_height) (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); + void (* get_width_for_height) (GtkExtendedCell *cell, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width); + void (* get_height_for_width) (GtkExtendedCell *cell, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height); }; GType gtk_extended_cell_get_type (void) G_GNUC_CONST; -void gtk_extended_cell_get_desired_size (GtkExtendedCell *cell, - GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); - - +void gtk_extended_cell_get_desired_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +void gtk_extended_cell_get_desired_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint *minimum_size, + gint *natural_size); +void gtk_extended_cell_get_width_for_height (GtkExtendedCell *cell, + GtkWidget *widget, + gint height, + gint *minimum_width, + gint *natural_width); +void gtk_extended_cell_get_height_for_width (GtkExtendedCell *cell, + GtkWidget *widget, + gint width, + gint *minimum_height, + gint *natural_height); G_END_DECLS diff --git a/gtk/gtkextendedlayout.c b/gtk/gtkextendedlayout.c index a8293e32de..0da095342b 100644 --- a/gtk/gtkextendedlayout.c +++ b/gtk/gtkextendedlayout.c @@ -24,9 +24,14 @@ #include #include "gtkextendedlayout.h" #include "gtksizegroup.h" +#include "gtkprivate.h" #include "gtkintl.h" #include "gtkalias.h" + +#define DEBUG_EXTENDED_LAYOUT 0 + + GType gtk_extended_layout_get_type (void) { @@ -45,32 +50,40 @@ gtk_extended_layout_get_type (void) return extended_layout_type; } -/** - * gtk_extended_layout_get_desired_size: - * @layout: a #GtkExtendedLayout instance - * @minimum_size: location for storing the minimum size, or %NULL - * @natural_size: location for storing the preferred size, or %NULL - * - * Retreives a widget's minimum and natural size and caches the values. - * - * This api will consider any restrictions imposed by - * #GtkSizeGroups or previous calls to gtk_widget_set_size_request(). - * - * - * Since: 3.0 - */ -void -gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) + + + +/* looks for a cached size request for this for_size. If not + * found, returns the oldest entry so it can be overwritten */ +static gboolean +_gtk_extended_layout_get_cached_desired_size (gfloat for_size, + GtkDesiredSize *cached_sizes, + GtkDesiredSize **result) { - g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); - g_return_if_fail (NULL != minimum_size || NULL != natural_size); + guint i; - _gtk_size_group_compute_desired_size (GTK_WIDGET (layout), minimum_size, natural_size); -} + *result = &cached_sizes[0]; + for (i = 0; i < GTK_N_CACHED_SIZES; i++) + { + GtkDesiredSize *cs; + cs = &cached_sizes[i]; + + if (cs->age > 0 && + cs->for_size == for_size) + { + *result = cs; + return TRUE; + } + else if (cs->age < (*result)->age) + { + *result = cs; + } + } + + return FALSE; +} /** * gtk_extended_layout_is_height_for_width: @@ -99,6 +112,147 @@ gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout) return TRUE; } +/** + * gtk_extended_layout_get_desired_width: + * @layout: a #GtkExtendedLayout instance + * @minimum_width: location to store the minimum size, or %NULL + * @natural_width: location to store the natural size, or %NULL + * + * Retreives a widget's minimum and natural size in a single dimension. + * + * Since: 3.0 + */ +void +gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_width, + gint *natural_width) +{ + GtkWidgetAuxInfo *aux_info; + gboolean found_in_cache = FALSE; + GtkDesiredSize *cached_size; + + g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); + g_return_if_fail (minimum_width != NULL || natural_width != NULL); + + aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE); + + cached_size = &aux_info->desired_widths[0]; + + if (GTK_WIDGET_WIDTH_REQUEST_NEEDED (layout) == FALSE) + found_in_cache = _gtk_extended_layout_get_cached_desired_size (-1, aux_info->desired_widths, + &cached_size); + + if (!found_in_cache) + { + GtkRequisition requisition; + gint minimum_width = 0, natural_width = 0; + + /* Unconditionally envoke size-request and use those return values as + * the base end of our values */ + _gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition); + + /* Envoke this after, default GtkWidgetClass will simply copy over widget->requisition + */ + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, + &minimum_width, + &natural_width); + + + cached_size->minimum_size = MAX (minimum_width, requisition.width); + cached_size->natural_size = MAX (natural_width, requisition.width); + cached_size->for_size = -1; + cached_size->age = aux_info->cached_width_age; + + aux_info->cached_width_age ++; + + GTK_PRIVATE_UNSET_FLAG (layout, GTK_WIDTH_REQUEST_NEEDED); + } + + if (minimum_width) + *minimum_width = cached_size->minimum_size; + + if (natural_width) + *natural_width = cached_size->natural_size; + +#if DEBUG_EXTENDED_LAYOUT + g_message ("%s returning minimum width: %d and natural width: %d", + G_OBJECT_TYPE_NAME (layout), + cached_size->minimum_size, + cached_size->natural_size); +#endif +} + + +/** + * gtk_extended_layout_get_desired_height: + * @layout: a #GtkExtendedLayout instance + * @minimum_width: location to store the minimum size, or %NULL + * @natural_width: location to store the natural size, or %NULL + * + * Retreives a widget's minimum and natural size in a single dimension. + * + * Since: 3.0 + */ +void +gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_height, + gint *natural_height) +{ + GtkWidgetAuxInfo *aux_info; + gboolean found_in_cache = FALSE; + GtkDesiredSize *cached_size; + + g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); + g_return_if_fail (minimum_height != NULL || natural_height != NULL); + + aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE); + + cached_size = &aux_info->desired_heights[0]; + + if (GTK_WIDGET_HEIGHT_REQUEST_NEEDED (layout) == FALSE) + found_in_cache = _gtk_extended_layout_get_cached_desired_size (-1, aux_info->desired_heights, + &cached_size); + + if (!found_in_cache) + { + GtkRequisition requisition; + gint minimum_height = 0, natural_height = 0; + + /* Unconditionally envoke size-request and use those return values as + * the base end of our values */ + _gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition); + + /* Envoke this after, default GtkWidgetClass will simply copy over widget->requisition + */ + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, + &minimum_height, + &natural_height); + + cached_size->minimum_size = MAX (minimum_height, requisition.height); + cached_size->natural_size = MAX (natural_height, requisition.height); + cached_size->for_size = -1; + cached_size->age = aux_info->cached_height_age; + + aux_info->cached_height_age ++; + + GTK_PRIVATE_UNSET_FLAG (layout, GTK_HEIGHT_REQUEST_NEEDED); + } + + if (minimum_height) + *minimum_height = cached_size->minimum_size; + + if (natural_height) + *natural_height = cached_size->natural_size; + + +#if DEBUG_EXTENDED_LAYOUT + g_message ("%s returning minimum height: %d and natural height: %d", + G_OBJECT_TYPE_NAME (layout), + cached_size->minimum_size, + cached_size->natural_size); +#endif +} + /** @@ -106,7 +260,7 @@ gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout) * @layout: a #GtkExtendedLayout instance * @height: the size which is available for allocation * @minimum_size: location for storing the minimum size, or %NULL - * @natural_size: location for storing the preferred size, or %NULL + * @natural_size: location for storing the natural size, or %NULL * * Retreives a widget's desired width if it would be given * the specified @height. @@ -119,20 +273,61 @@ gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout, gint *minimum_width, gint *natural_width) { - GtkExtendedLayoutIface *iface; + GtkWidgetAuxInfo *aux_info; + gboolean found_in_cache = FALSE; + GtkDesiredSize *cached_size; g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); + g_return_if_fail (minimum_width != NULL || natural_width != NULL); - /* XXX Maybe here we do _gtk_size_group_compute_width_for_height() - * and return hard coded minimum widths/heights for for widgets with - * explicit size requests as well as fetch the common minimum/natural - * widths/heights for size grouped widgets. - */ + aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE); - iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout); - iface->get_width_for_height (layout, height, minimum_width, natural_width); + cached_size = &aux_info->desired_widths[0]; + + if (GTK_WIDGET_WIDTH_REQUEST_NEEDED (layout) == FALSE) + found_in_cache = _gtk_extended_layout_get_cached_desired_size (height, aux_info->desired_widths, + &cached_size); + + if (!found_in_cache) + { + GtkRequisition requisition; + gint minimum_width = 0, natural_width = 0; + + /* Unconditionally envoke size-request and use those return values as + * the base end of our values */ + _gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition); + + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_width_for_height (layout, + height, + &minimum_width, + &natural_width); + + cached_size->minimum_size = MAX (minimum_width, requisition.width); + cached_size->natural_size = MAX (natural_width, requisition.width); + cached_size->for_size = height; + cached_size->age = aux_info->cached_width_age; + + aux_info->cached_width_age++; + + GTK_PRIVATE_UNSET_FLAG (layout, GTK_WIDTH_REQUEST_NEEDED); + } + + + if (minimum_width) + *minimum_width = cached_size->minimum_size; + + if (natural_width) + *natural_width = cached_size->natural_size; g_assert (!minimum_width || !natural_width || *minimum_width <= *natural_width); + +#if DEBUG_EXTENDED_LAYOUT + g_message ("%s width for height: %d is minimum %d and natural: %d", + G_OBJECT_TYPE_NAME (layout), height, + cached_size->minimum_size, + cached_size->natural_size); +#endif + } /** @@ -140,7 +335,7 @@ gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout, * @layout: a #GtkExtendedLayout instance * @width: the size which is available for allocation * @minimum_size: location for storing the minimum size, or %NULL - * @natural_size: location for storing the preferred size, or %NULL + * @natural_size: location for storing the natural size, or %NULL * * Retreives a widget's desired height if it would be given * the specified @width. @@ -153,15 +348,131 @@ gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout, gint *minimum_height, gint *natural_height) { - GtkExtendedLayoutIface *iface; + GtkWidgetAuxInfo *aux_info; + gboolean found_in_cache = FALSE; + GtkDesiredSize *cached_size; g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); + g_return_if_fail (minimum_height != NULL || natural_height != NULL); - iface = GTK_EXTENDED_LAYOUT_GET_IFACE (layout); - iface->get_height_for_width (layout, width, minimum_height, natural_height); + aux_info = _gtk_widget_get_aux_info (GTK_WIDGET (layout), TRUE); + + cached_size = &aux_info->desired_heights[0]; + + if (GTK_WIDGET_HEIGHT_REQUEST_NEEDED (layout) == FALSE) + found_in_cache = _gtk_extended_layout_get_cached_desired_size (width, aux_info->desired_heights, + &cached_size); + + if (!found_in_cache) + { + GtkRequisition requisition; + gint minimum_height = 0, natural_height = 0; + + /* Unconditionally envoke size-request and use those return values as + * the base end of our values */ + _gtk_size_group_compute_requisition (GTK_WIDGET (layout), &requisition); + + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_height_for_width (layout, + width, + &minimum_height, + &natural_height); + + cached_size->minimum_size = MAX (minimum_height, requisition.height); + cached_size->natural_size = MAX (natural_height, requisition.height); + cached_size->for_size = width; + cached_size->age = aux_info->cached_height_age; + + aux_info->cached_height_age++; + + GTK_PRIVATE_UNSET_FLAG (layout, GTK_HEIGHT_REQUEST_NEEDED); + } + + + if (minimum_height) + *minimum_height = cached_size->minimum_size; + + if (natural_height) + *natural_height = cached_size->natural_size; g_assert (!minimum_height || !natural_height || *minimum_height <= *natural_height); + +#if DEBUG_EXTENDED_LAYOUT + g_message ("%s height for width: %d is minimum %d and natural: %d", + G_OBJECT_TYPE_NAME (layout), width, + cached_size->minimum_size, + cached_size->natural_size); +#endif } + + + +/** + * gtk_extended_layout_get_desired_size: + * @layout: a #GtkExtendedLayout instance + * @width: the size which is available for allocation + * @minimum_size: location for storing the minimum size, or %NULL + * @natural_size: location for storing the natural size, or %NULL + * + * Retreives the minimum and natural size of a widget taking + * into account the widget's preference for height-for-width management. + * + * This is used to retreive a suitable size by container widgets whom dont + * impose any restrictions on the child placement, examples of these are + * #GtkWindow and #GtkScrolledWindow. + * + * Since: 3.0 + */ +void +gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout, + GtkRequisition *minimum_size, + GtkRequisition *natural_size) +{ + gint min_width, nat_width; + gint min_height, nat_height; + + g_return_if_fail (GTK_IS_EXTENDED_LAYOUT (layout)); + + if (gtk_extended_layout_is_height_for_width (layout)) + { + gtk_extended_layout_get_desired_width (layout, &min_width, &nat_width); + gtk_extended_layout_get_height_for_width (layout, nat_width, &min_height, &nat_height); + + /* The minimum size here is the minimum height for the natrual width */ + if (minimum_size) + { + minimum_size->width = nat_width; + minimum_size->height = min_height; + } + + } + else + { + gtk_extended_layout_get_desired_height (layout, &min_height, &nat_height); + gtk_extended_layout_get_height_for_width (layout, nat_height, &min_width, &nat_width); + + /* The minimum size here is the minimum width for the natrual height */ + if (minimum_size) + { + minimum_size->width = min_width; + minimum_size->height = nat_height; + } + } + + if (natural_size) + { + natural_size->width = nat_width; + natural_size->height = nat_height; + } + + +#if DEBUG_EXTENDED_LAYOUT + g_message ("get_desired_size called on a %s; minimum width: %d natural width: %d minimum height %d natural height %d", + G_OBJECT_TYPE_NAME (layout), min_width, nat_width, min_height, nat_height); +#endif +} + + + #define __GTK_EXTENDED_LAYOUT_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtkextendedlayout.h b/gtk/gtkextendedlayout.h index 1d0d531d42..65faa9e282 100644 --- a/gtk/gtkextendedlayout.h +++ b/gtk/gtkextendedlayout.h @@ -41,15 +41,14 @@ struct _GtkExtendedLayoutIface GTypeInterface g_iface; /* virtual table */ - - - /* TODO: Change for get_desired_width()/get_desired_height() for clarity sake */ - void (* get_desired_size) (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); - gboolean (* is_height_for_width) (GtkExtendedLayout *layout); - + + void (* get_desired_width) (GtkExtendedLayout *layout, + gint *minimum_width, + gint *natural_width); + void (* get_desired_height) (GtkExtendedLayout *layout, + gint *minimum_height, + gint *natural_height); void (* get_width_for_height) (GtkExtendedLayout *layout, gint height, gint *minimum_width, @@ -62,12 +61,13 @@ struct _GtkExtendedLayoutIface GType gtk_extended_layout_get_type (void) G_GNUC_CONST; -void gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); - - gboolean gtk_extended_layout_is_height_for_width (GtkExtendedLayout *layout); +void gtk_extended_layout_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_width, + gint *natural_width); +void gtk_extended_layout_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_height, + gint *natural_height); void gtk_extended_layout_get_width_for_height (GtkExtendedLayout *layout, gint height, gint *minimum_width, @@ -77,6 +77,10 @@ void gtk_extended_layout_get_height_for_width (GtkExtendedLayout *layout, gint *minimum_height, gint *natural_height); +void gtk_extended_layout_get_desired_size (GtkExtendedLayout *layout, + GtkRequisition *minimum_size, + GtkRequisition *natural_size); + G_END_DECLS diff --git a/gtk/gtklabel.c b/gtk/gtklabel.c index dd30b21e60..f8294f21d5 100644 --- a/gtk/gtklabel.c +++ b/gtk/gtklabel.c @@ -303,9 +303,12 @@ static void emit_activate_link (GtkLabel *label, static void gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface); -static void gtk_label_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +static void gtk_label_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_label_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); static void gtk_label_get_width_for_height (GtkExtendedLayout *layout, gint height, gint *minimum_width, @@ -348,14 +351,6 @@ add_move_binding (GtkBindingSet *binding_set, G_TYPE_BOOLEAN, TRUE); } -static void -gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface) -{ - iface->get_desired_size = gtk_label_get_desired_size; - iface->get_width_for_height = gtk_label_get_width_for_height; - iface->get_height_for_width = gtk_label_get_height_for_width; -} - static void gtk_label_class_init (GtkLabelClass *class) { @@ -3198,16 +3193,29 @@ get_single_line_height (GtkWidget *widget, return PANGO_PIXELS (ascent + descent); } + + +static void +gtk_label_layout_interface_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_label_get_desired_width; + iface->get_desired_height = gtk_label_get_desired_height; + iface->get_width_for_height = gtk_label_get_width_for_height; + iface->get_height_for_width = gtk_label_get_height_for_width; +} + static void gtk_label_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkLabelPrivate *priv = GTK_LABEL_GET_PRIVATE (layout); GtkLabel *label = GTK_LABEL (layout); PangoRectangle required_rect; GtkWidgetAuxInfo *aux_info; PangoLayout *natural_layout; + gint minimum = 0, natural = 0; /* * If word wrapping is on, then the height requisition can depend @@ -3268,9 +3276,10 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, /* XXX TODO: Ideally for wrapping labels, the width should be one char or the length * of the longest word in the text depending on wrap mode. */ - - minimum_size->width = required_rect.width + label->misc.xpad * 2; - minimum_size->height = required_rect.height + label->misc.ypad * 2; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + minimum = required_rect.width + label->misc.xpad * 2; + else + minimum = required_rect.height + label->misc.ypad * 2; /* Natural size */ natural_layout = pango_layout_copy (label->layout); @@ -3293,12 +3302,38 @@ gtk_label_get_desired_size (GtkExtendedLayout *layout, required_rect.width = PANGO_PIXELS_CEIL (required_rect.width); required_rect.height = PANGO_PIXELS_CEIL (required_rect.height); - natural_size->width = required_rect.width + label->misc.xpad * 2; - natural_size->height = required_rect.height + label->misc.ypad * 2; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + natural = required_rect.width + label->misc.xpad * 2; + else + natural = required_rect.height + label->misc.ypad * 2; g_object_unref (natural_layout); + + if (minimum_size) + *minimum_size = minimum; + + if (natural_size) + *natural_size = natural; +} + + +static void +gtk_label_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_label_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_label_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_label_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } + static void get_size_for_allocation (GtkLabel *label, GtkOrientation orientation, @@ -3351,18 +3386,7 @@ gtk_label_get_width_for_height (GtkExtendedLayout *layout, if (90 == angle || 270 == angle) get_size_for_allocation (label, GTK_ORIENTATION_VERTICAL, height, minimum_width, natural_width); else - { - GtkRequisition minimum_size, natural_size; - - gtk_extended_layout_get_desired_size (layout, - minimum_width ? &minimum_size : NULL, - natural_width ? &natural_size : NULL); - - if (minimum_width) - *minimum_width = minimum_size.width; - if (natural_width) - *natural_width = natural_size.width; - } + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width); } static void @@ -3377,18 +3401,7 @@ gtk_label_get_height_for_width (GtkExtendedLayout *layout, if (0 == angle || 180 == angle) get_size_for_allocation (label, GTK_ORIENTATION_HORIZONTAL, width, minimum_height, natural_height); else - { - GtkRequisition minimum_size, natural_size; - - gtk_extended_layout_get_desired_size (layout, - minimum_height ? &minimum_size : NULL, - natural_height ? &natural_size : NULL); - - if (minimum_height) - *minimum_height = minimum_size.height; - if (natural_height) - *natural_height = natural_size.height; - } + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height); } static void @@ -3617,8 +3630,10 @@ get_layout_location (GtkLabel *label, } else { - req_width = widget->requisition.width; - req_height = widget->requisition.height; + req_width = logical.width; + req_height = logical.height; +/* req_width = widget->requisition.width; */ +/* req_height = widget->requisition.height; */ } x = floor (widget->allocation.x + (gint)misc->xpad + diff --git a/gtk/gtkprivate.h b/gtk/gtkprivate.h index 7ba5a5db62..4c5efb374b 100644 --- a/gtk/gtkprivate.h +++ b/gtk/gtkprivate.h @@ -35,37 +35,42 @@ G_BEGIN_DECLS */ typedef enum { - PRIVATE_GTK_USER_STYLE = 1 << 0, - PRIVATE_GTK_RESIZE_PENDING = 1 << 2, - PRIVATE_GTK_HAS_POINTER = 1 << 3, /* If the pointer is above a window belonging to the widget */ - PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */ - PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5, - PRIVATE_GTK_IN_REPARENT = 1 << 6, - PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */ - PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */ - PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */ - PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */ - PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */ - PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */ - PRIVATE_GTK_REQUEST_NEEDED = 1 << 13 /* Whether we need to call gtk_widget_size_request */ + PRIVATE_GTK_USER_STYLE = 1 << 0, + PRIVATE_GTK_RESIZE_PENDING = 1 << 2, + PRIVATE_GTK_HAS_POINTER = 1 << 3, /* If the pointer is above a window belonging to the widget */ + PRIVATE_GTK_SHADOWED = 1 << 4, /* If there is a grab in effect shadowing the widget */ + PRIVATE_GTK_HAS_SHAPE_MASK = 1 << 5, + PRIVATE_GTK_IN_REPARENT = 1 << 6, + PRIVATE_GTK_DIRECTION_SET = 1 << 7, /* If the reading direction is not DIR_NONE */ + PRIVATE_GTK_DIRECTION_LTR = 1 << 8, /* If the reading direction is DIR_LTR */ + PRIVATE_GTK_ANCHORED = 1 << 9, /* If widget has a GtkWindow ancestor */ + PRIVATE_GTK_CHILD_VISIBLE = 1 << 10, /* If widget should be mapped when parent is mapped */ + PRIVATE_GTK_REDRAW_ON_ALLOC = 1 << 11, /* If we should queue a draw on the entire widget when it is reallocated */ + PRIVATE_GTK_ALLOC_NEEDED = 1 << 12, /* If we we should allocate even if the allocation is the same */ + PRIVATE_GTK_REQUEST_NEEDED = 1 << 13, /* Whether we need to call gtk_widget_size_request */ + PRIVATE_GTK_WIDTH_REQUEST_NEEDED = 1 << 14, /* Whether we need to call gtk_extended_layout_get_desired_width */ + PRIVATE_GTK_HEIGHT_REQUEST_NEEDED = 1 << 15 /* Whether we need to call gtk_extended_layout_get_desired_height */ + } GtkPrivateFlags; /* Macros for extracting a widgets private_flags from GtkWidget. */ -#define GTK_PRIVATE_FLAGS(wid) (GTK_WIDGET (wid)->private_flags) -#define GTK_WIDGET_USER_STYLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0) -#define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0) -#define GTK_WIDGET_HAS_POINTER(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_POINTER) != 0) -#define GTK_WIDGET_SHADOWED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_SHADOWED) != 0) -#define GTK_WIDGET_HAS_SHAPE_MASK(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0) -#define GTK_WIDGET_IN_REPARENT(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0) -#define GTK_WIDGET_DIRECTION_SET(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_SET) != 0) -#define GTK_WIDGET_DIRECTION_LTR(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0) -#define GTK_WIDGET_ANCHORED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0) -#define GTK_WIDGET_CHILD_VISIBLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0) -#define GTK_WIDGET_REDRAW_ON_ALLOC(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0) -#define GTK_WIDGET_ALLOC_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0) -#define GTK_WIDGET_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0) +#define GTK_PRIVATE_FLAGS(wid) (GTK_WIDGET (wid)->private_flags) +#define GTK_WIDGET_USER_STYLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_USER_STYLE) != 0) +#define GTK_CONTAINER_RESIZE_PENDING(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_RESIZE_PENDING) != 0) +#define GTK_WIDGET_HAS_POINTER(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_POINTER) != 0) +#define GTK_WIDGET_SHADOWED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_SHADOWED) != 0) +#define GTK_WIDGET_HAS_SHAPE_MASK(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HAS_SHAPE_MASK) != 0) +#define GTK_WIDGET_IN_REPARENT(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_IN_REPARENT) != 0) +#define GTK_WIDGET_DIRECTION_SET(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_SET) != 0) +#define GTK_WIDGET_DIRECTION_LTR(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_DIRECTION_LTR) != 0) +#define GTK_WIDGET_ANCHORED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ANCHORED) != 0) +#define GTK_WIDGET_CHILD_VISIBLE(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_CHILD_VISIBLE) != 0) +#define GTK_WIDGET_REDRAW_ON_ALLOC(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REDRAW_ON_ALLOC) != 0) +#define GTK_WIDGET_ALLOC_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_ALLOC_NEEDED) != 0) +#define GTK_WIDGET_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_REQUEST_NEEDED) != 0) +#define GTK_WIDGET_WIDTH_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_WIDTH_REQUEST_NEEDED) != 0) +#define GTK_WIDGET_HEIGHT_REQUEST_NEEDED(obj) ((GTK_PRIVATE_FLAGS (obj) & PRIVATE_GTK_HEIGHT_REQUEST_NEEDED) != 0) /* Macros for setting and clearing private widget flags. * we use a preprocessor string concatenation here for a clear diff --git a/gtk/gtkscrolledwindow.c b/gtk/gtkscrolledwindow.c index 5634862128..da7a968c1f 100644 --- a/gtk/gtkscrolledwindow.c +++ b/gtk/gtkscrolledwindow.c @@ -142,6 +142,20 @@ static void gtk_scrolled_window_adjustment_changed (GtkAdjustment *adjus static void gtk_scrolled_window_update_real_placement (GtkScrolledWindow *scrolled_window); static void gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_scrolled_window_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_scrolled_window_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_scrolled_window_get_height_for_width (GtkExtendedLayout *layout, + gint width, + gint *minimum_height, + gint *natural_height); +static void gtk_scrolled_window_get_width_for_height (GtkExtendedLayout *layout, + gint width, + gint *minimum_height, + gint *natural_height); static guint signals[LAST_SIGNAL] = {0}; @@ -1706,10 +1720,20 @@ _gtk_scrolled_window_get_scrollbar_spacing (GtkScrolledWindow *scrolled_window) } } + static void -gtk_scrolled_window_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_scrolled_window_get_desired_width; + iface->get_desired_height = gtk_scrolled_window_get_desired_height; + iface->get_height_for_width = gtk_scrolled_window_get_height_for_width; + iface->get_width_for_height = gtk_scrolled_window_get_width_for_height; +} + +static void +gtk_scrolled_window_get_desired_size (GtkExtendedLayout *layout, + GtkRequisition *minimum_size, + GtkRequisition *natural_size) { GtkScrolledWindow *scrolled_window; GtkBin *bin; @@ -1821,62 +1845,58 @@ gtk_scrolled_window_extended_layout_get_desired_size (GtkExtendedLayout *layout, } } -static void -gtk_scrolled_window_extended_layout_get_height_for_width (GtkExtendedLayout *layout, - gint width, - gint *minimum_height, - gint *natural_height) +static void +gtk_scrolled_window_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { - GtkRequisition minimum_size; - GtkRequisition natural_size; + GtkRequisition minimum, natural; - g_return_if_fail (GTK_IS_WIDGET (layout)); + gtk_scrolled_window_get_desired_size (layout, &minimum, &natural); + + if (minimum_size) + *minimum_size = minimum.width; -#if 0 - TODO: integrate height-for-width with size-groups -#else - gtk_extended_layout_get_desired_size (layout, - minimum_height ? &minimum_size : NULL, - natural_height ? &natural_size : NULL); - - if (minimum_height) - *minimum_height = minimum_size.height; - if (natural_height) - *natural_height = natural_size.height; -#endif + if (natural_size) + *natural_size = natural.width; } static void -gtk_scrolled_window_extended_layout_get_width_for_height (GtkExtendedLayout *layout, - gint height, - gint *minimum_width, - gint *natural_width) +gtk_scrolled_window_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + GtkRequisition minimum, natural; + + gtk_scrolled_window_get_desired_size (layout, &minimum, &natural); + + if (minimum_size) + *minimum_size = minimum.height; + + if (natural_size) + *natural_size = natural.height; +} + +static void +gtk_scrolled_window_get_height_for_width (GtkExtendedLayout *layout, + gint width, + gint *minimum_height, + gint *natural_height) { - GtkRequisition minimum_size; - GtkRequisition natural_size; - g_return_if_fail (GTK_IS_WIDGET (layout)); -#if 0 - TODO: integrate width-for-height with size-groups -#else - gtk_extended_layout_get_desired_size (layout, - minimum_width ? &minimum_size : NULL, - natural_width ? &natural_size : NULL); - - if (minimum_width) - *minimum_width = minimum_size.width; - if (natural_width) - *natural_width = natural_size.width; -#endif + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_height (layout, minimum_height, natural_height); } static void -gtk_scrolled_window_extended_layout_init (GtkExtendedLayoutIface *iface) +gtk_scrolled_window_get_width_for_height (GtkExtendedLayout *layout, + gint height, + gint *minimum_width, + gint *natural_width) { - iface->get_desired_size = gtk_scrolled_window_extended_layout_get_desired_size; - iface->get_width_for_height = gtk_scrolled_window_extended_layout_get_width_for_height; - iface->get_height_for_width = gtk_scrolled_window_extended_layout_get_height_for_width; + g_return_if_fail (GTK_IS_WIDGET (layout)); + + GTK_EXTENDED_LAYOUT_GET_IFACE (layout)->get_desired_width (layout, minimum_width, natural_width); } #define __GTK_SCROLLED_WINDOW_C__ diff --git a/gtk/gtksizegroup.c b/gtk/gtksizegroup.c index b9ac3e2e9e..b1abfbe6ca 100644 --- a/gtk/gtksizegroup.c +++ b/gtk/gtksizegroup.c @@ -25,18 +25,8 @@ #include "gtkprivate.h" #include "gtksizegroup.h" #include "gtkbuildable.h" -#include "gtkextendedlayout.h" #include "gtkalias.h" -#define GTK_SIZE_GROUP_GET_PRIVATE(o) (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_SIZE_GROUP, GtkSizeGroupPrivate)) - -typedef struct _GtkSizeGroupPrivate GtkSizeGroupPrivate; - -struct _GtkSizeGroupPrivate -{ - GtkRequisition natural_size; -}; - enum { PROP_0, PROP_MODE, @@ -164,6 +154,8 @@ real_queue_resize (GtkWidget *widget) { GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED); GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED); if (widget->parent) _gtk_container_queue_resize (GTK_CONTAINER (widget->parent)); @@ -332,7 +324,6 @@ gtk_size_group_class_init (GtkSizeGroupClass *klass) GTK_PARAM_READWRITE)); initialize_size_group_quarks (); - g_type_class_add_private (klass, sizeof (GtkSizeGroupPrivate)); } static void @@ -607,49 +598,25 @@ gtk_size_group_get_widgets (GtkSizeGroup *size_group) return size_group->widgets; } -static void -get_base_dimensions (GtkWidget *widget, - GtkSizeGroupMode mode, - gint *minimum_size, - gint *natural_size) +static gint +get_base_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) { GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE); if (mode == GTK_SIZE_GROUP_HORIZONTAL) { - if (minimum_size) - { - if (aux_info && aux_info->width > 0) - *minimum_size = aux_info->width; - else - *minimum_size = widget->requisition.width; - } - - if (natural_size) - { - if (aux_info) - *natural_size = aux_info->natural_size.width; - else - *natural_size = widget->requisition.width; - } + if (aux_info && aux_info->width > 0) + return aux_info->width; + else + return widget->requisition.width; } else { - if (minimum_size) - { - if (aux_info && aux_info->height > 0) - *minimum_size = aux_info->height; - else - *minimum_size = widget->requisition.height; - } - - if (natural_size) - { - if (aux_info) - *natural_size = aux_info->natural_size.height; - else - *natural_size = widget->requisition.height; - } + if (aux_info && aux_info->height > 0) + return aux_info->height; + else + return widget->requisition.height; } } @@ -658,72 +625,31 @@ do_size_request (GtkWidget *widget) { if (GTK_WIDGET_REQUEST_NEEDED (widget)) { - GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, TRUE); - GtkRequisition extended_minimum; - gtk_widget_ensure_style (widget); GTK_PRIVATE_UNSET_FLAG (widget, GTK_REQUEST_NEEDED); - - /* First, allow client code to; extended classes or signal connections; to - * modify the initial size request. - * - * Note here that there is no convention of filling the argument or widget->requisition, - * so we have no choice but to fire size request with this pointer. - */ - g_signal_emit_by_name (widget, "size-request", &widget->requisition); - - /* Now get the extended layout minimum and natural size - */ - extended_minimum.width = 0; - extended_minimum.height = 0; - - GTK_EXTENDED_LAYOUT_GET_IFACE - (widget)->get_desired_size (GTK_EXTENDED_LAYOUT (widget), - &extended_minimum, - &aux_info->natural_size); - - /* Base the base widget requisition on both the size-requst and the extended layout size - */ - widget->requisition.width = MAX (widget->requisition.width, extended_minimum.width); - widget->requisition.height = MAX (widget->requisition.height, extended_minimum.height); - - /* Additionally allow a "size-request" to overflow the natural size. - */ - aux_info->natural_size.width = MAX (aux_info->natural_size.width, widget->requisition.width); - aux_info->natural_size.height = MAX (aux_info->natural_size.height, widget->requisition.height); - - /* Assert that pure extended layout cases return initial minimum sizes smaller or equal - * to their possible natural size. - * - * Note that this only determines the return of gtk_widget_get_desired_size() and caches - * the initial hints. Height for width cases will further be addressed in containers - * using gtk_extended_layout_get_height_for_width(). - */ - g_assert (widget->requisition.width <= aux_info->natural_size.width); - g_assert (widget->requisition.height <= aux_info->natural_size.height); - + g_signal_emit_by_name (widget, + "size-request", + &widget->requisition); } } -static void -compute_base_dimensions (GtkWidget *widget, - GtkSizeGroupMode mode, - gint *minimum_size, - gint *natural_size) +static gint +compute_base_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) { do_size_request (widget); - get_base_dimensions (widget, mode, minimum_size, natural_size); + + return get_base_dimension (widget, mode); } -static void +static gint compute_dimension (GtkWidget *widget, - GtkSizeGroupMode mode, - gint *minimum_size, - gint *natural_size) + GtkSizeGroupMode mode) { GSList *widgets = NULL; GSList *groups = NULL; GSList *tmp_list; + gint result = 0; add_widget_to_closure (widget, mode, &groups, &widgets); @@ -734,26 +660,16 @@ compute_dimension (GtkWidget *widget, if (!groups) { - compute_base_dimensions (widget, mode, minimum_size, natural_size); + result = compute_base_dimension (widget, mode); } else { GtkSizeGroup *group = groups->data; - GtkSizeGroupPrivate *priv = GTK_SIZE_GROUP_GET_PRIVATE (group); - - gint result_minimum_size = 0; - gint result_natural_size = 0; if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width) - { - result_minimum_size = group->requisition.width; - result_natural_size = priv->natural_size.width; - } + result = group->requisition.width; else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height) - { - result_minimum_size = group->requisition.height; - result_natural_size = priv->natural_size.height; - } + result = group->requisition.height; else { tmp_list = widgets; @@ -761,20 +677,13 @@ compute_dimension (GtkWidget *widget, { GtkWidget *tmp_widget = tmp_list->data; - gint tmp_widget_minimum_size; - gint tmp_widget_natural_size; - - compute_base_dimensions (tmp_widget, mode, - &tmp_widget_minimum_size, - &tmp_widget_natural_size); + gint dimension = compute_base_dimension (tmp_widget, mode); - if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden) - { - if (result_minimum_size < tmp_widget_minimum_size) - result_minimum_size = tmp_widget_minimum_size; - if (result_natural_size < tmp_widget_natural_size) - result_natural_size = tmp_widget_natural_size; - } + if (gtk_widget_get_mapped (tmp_widget) || !group->ignore_hidden) + { + if (dimension > result) + result = dimension; + } tmp_list = tmp_list->next; } @@ -783,45 +692,38 @@ compute_dimension (GtkWidget *widget, while (tmp_list) { GtkSizeGroup *tmp_group = tmp_list->data; - GtkSizeGroupPrivate *tmp_priv = GTK_SIZE_GROUP_GET_PRIVATE (tmp_group); if (mode == GTK_SIZE_GROUP_HORIZONTAL) { tmp_group->have_width = TRUE; - tmp_group->requisition.width = result_minimum_size; - tmp_priv->natural_size.width = result_natural_size; + tmp_group->requisition.width = result; } else { tmp_group->have_height = TRUE; - tmp_group->requisition.height = result_minimum_size; - tmp_priv->natural_size.height = result_natural_size; + tmp_group->requisition.height = result; } tmp_list = tmp_list->next; } } - - if (minimum_size) - *minimum_size = result_minimum_size; - if (natural_size) - *natural_size = result_natural_size; } g_slist_foreach (widgets, (GFunc)g_object_unref, NULL); g_slist_free (widgets); g_slist_free (groups); + + return result; } -static void -get_dimensions (GtkWidget *widget, - GtkSizeGroupMode mode, - gint *minimum_size, - gint *natural_size) +static gint +get_dimension (GtkWidget *widget, + GtkSizeGroupMode mode) { GSList *widgets = NULL; GSList *groups = NULL; + gint result = 0; add_widget_to_closure (widget, mode, &groups, &widgets); @@ -830,69 +732,38 @@ get_dimensions (GtkWidget *widget, if (!groups) { - get_base_dimensions (widget, mode, minimum_size, natural_size); + result = get_base_dimension (widget, mode); } else { GtkSizeGroup *group = groups->data; - GtkSizeGroupPrivate *priv = GTK_SIZE_GROUP_GET_PRIVATE (group); if (mode == GTK_SIZE_GROUP_HORIZONTAL && group->have_width) - { - if (minimum_size) - *minimum_size = group->requisition.width; - if (natural_size) - *natural_size = priv->natural_size.width; - } + result = group->requisition.width; else if (mode == GTK_SIZE_GROUP_VERTICAL && group->have_height) - { - if (minimum_size) - *minimum_size = group->requisition.height; - if (natural_size) - *natural_size = priv->natural_size.height; - } + result = group->requisition.height; } g_slist_free (widgets); g_slist_free (groups); + + return result; } static void -get_fast_size (GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +get_fast_child_requisition (GtkWidget *widget, + GtkRequisition *requisition) { GtkWidgetAuxInfo *aux_info = _gtk_widget_get_aux_info (widget, FALSE); - if (minimum_size) - { - *minimum_size = widget->requisition; + *requisition = widget->requisition; - if (aux_info) - { - if (aux_info->width > 0) - minimum_size->width = aux_info->width; - if (aux_info->height > 0) - minimum_size->height = aux_info->height; - } - } - - if (natural_size) + if (aux_info) { - if (aux_info) - { - *natural_size = aux_info->natural_size; - - /* Explicit size request sets the baseline for natural size - * as well as the minimum size - */ - if (aux_info->width > natural_size->width) - natural_size->width = aux_info->width; - if (aux_info->height > natural_size->height) - natural_size->height = aux_info->height; - } - else - *natural_size = widget->requisition; + if (aux_info->width > 0) + requisition->width = aux_info->width; + if (aux_info && aux_info->height > 0) + requisition->height = aux_info->height; } } @@ -903,8 +774,6 @@ get_fast_size (GtkWidget *widget, * * Retrieve the "child requisition" of the widget, taking account grouping * of the widget's requisition with other widgets. - * - * Deprecated: 3.0: Use _gtk_size_group_compute_desired_size() instead **/ void _gtk_size_group_get_child_requisition (GtkWidget *widget, @@ -916,48 +785,52 @@ _gtk_size_group_get_child_requisition (GtkWidget *widget, { if (get_size_groups (widget)) { - get_dimensions (widget, GTK_SIZE_GROUP_HORIZONTAL, &requisition->width, NULL); - get_dimensions (widget, GTK_SIZE_GROUP_VERTICAL, &requisition->height, NULL); + requisition->width = get_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL); + requisition->height = get_dimension (widget, GTK_SIZE_GROUP_VERTICAL); /* Only do the full computation if we actually have size groups */ } else - get_fast_size (widget, requisition, NULL); + get_fast_child_requisition (widget, requisition); } } /** - * _gtk_size_group_compute_desired_size: + * _gtk_size_group_compute_requisition: * @widget: a #GtkWidget - * @minimum_size: location to store computed minimum size - * @natural_size: location to store computed natural size + * @requisition: location to store computed requisition. * - * Compute the desired size of a widget taking into account grouping of + * Compute the requisition of a widget taking into account grouping of * the widget's requisition with other widgets. **/ void -_gtk_size_group_compute_desired_size (GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +_gtk_size_group_compute_requisition (GtkWidget *widget, + GtkRequisition *requisition) { + gint width; + gint height; + initialize_size_group_quarks (); if (get_size_groups (widget)) { /* Only do the full computation if we actually have size groups */ + + width = compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL); + height = compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL); - compute_dimension (widget, GTK_SIZE_GROUP_HORIZONTAL, - minimum_size ? &minimum_size->width : NULL, - natural_size ? &natural_size->width : NULL); - compute_dimension (widget, GTK_SIZE_GROUP_VERTICAL, - minimum_size ? &minimum_size->height : NULL, - natural_size ? &natural_size->height : NULL); + if (requisition) + { + requisition->width = width; + requisition->height = height; + } } else { do_size_request (widget); - - get_fast_size (widget, minimum_size, natural_size); + + if (requisition) + get_fast_child_requisition (widget, requisition); } } diff --git a/gtk/gtksizegroup.h b/gtk/gtksizegroup.h index d82fbd5ca8..ecd2ceacf6 100644 --- a/gtk/gtksizegroup.h +++ b/gtk/gtksizegroup.h @@ -102,9 +102,8 @@ GSList * gtk_size_group_get_widgets (GtkSizeGroup *size_group); void _gtk_size_group_get_child_requisition (GtkWidget *widget, GtkRequisition *requisition); -void _gtk_size_group_compute_desired_size (GtkWidget *widget, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +void _gtk_size_group_compute_requisition (GtkWidget *widget, + GtkRequisition *requisition); void _gtk_size_group_queue_resize (GtkWidget *widget); G_END_DECLS diff --git a/gtk/gtksocket.c b/gtk/gtksocket.c index 52ad6ab032..e64f308011 100644 --- a/gtk/gtksocket.c +++ b/gtk/gtksocket.c @@ -68,7 +68,13 @@ static void gtk_socket_forall (GtkContainer *container, GtkCallback callback, gpointer callback_data); -static void gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface); +static void gtk_socket_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_socket_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_socket_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); /* Local data */ @@ -102,7 +108,7 @@ _gtk_socket_get_private (GtkSocket *socket) G_DEFINE_TYPE_WITH_CODE (GtkSocket, gtk_socket, GTK_TYPE_CONTAINER, G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT, - gtk_socket_extended_layout_interface_init)) + gtk_socket_extended_layout_init)) static void @@ -1013,18 +1019,29 @@ _gtk_socket_advance_toplevel_focus (GtkSocket *socket, } static void -gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimal_size, - GtkRequisition *desired_size) +gtk_socket_extended_layout_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_socket_get_desired_width; + iface->get_desired_height = gtk_socket_get_desired_height; +} + +static void +gtk_socket_get_desired_size (GtkExtendedLayout *layout, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkSocket *socket = GTK_SOCKET (layout); GtkSocketPrivate *priv; if (socket->plug_widget) { - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (socket->plug_widget), - minimal_size, - desired_size); + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (socket->plug_widget), + minimum_size, natural_size); + else + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (socket->plug_widget), + minimum_size, natural_size); } else { @@ -1038,37 +1055,44 @@ gtk_socket_extended_layout_get_desired_size (GtkExtendedLayout *layout, if (socket->is_mapped && priv->have_natural_size) { - if (minimal_size) + if (minimum_size) { - minimal_size->width = MAX (socket->request_width, 1); - minimal_size->height = MAX (socket->request_height, 1); + *minimum_size = + (orientation == GTK_ORIENTATION_HORIZONTAL) ? + MAX (socket->request_width, 1) : MAX (socket->request_height, 1); } - if (desired_size) + if (natural_size) { - desired_size->width = MAX (priv->natural_width, 1); - desired_size->height = MAX (priv->natural_height, 1); + *natural_size = + (orientation == GTK_ORIENTATION_HORIZONTAL) ? + MAX (priv->natural_width, 1) : MAX (priv->natural_height, 1); } } else { - if (minimal_size) - { - minimal_size->width = 1; - minimal_size->height = 1; - } - if (desired_size) - { - desired_size->width = 1; - desired_size->height = 1; - } + if (minimum_size) + *minimum_size = 1; + + if (natural_size) + *natural_size = 1; } } } static void -gtk_socket_extended_layout_interface_init (GtkExtendedLayoutIface *iface) +gtk_socket_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_socket_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_socket_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { - iface->get_desired_size = gtk_socket_extended_layout_get_desired_size; + gtk_socket_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } diff --git a/gtk/gtktreeview.c b/gtk/gtktreeview.c index 7343d678de..b42c5b2983 100644 --- a/gtk/gtktreeview.c +++ b/gtk/gtktreeview.c @@ -469,6 +469,13 @@ static void gtk_tree_view_buildable_add_child (GtkBuildable *tree_view, const gchar *type); static void gtk_tree_view_buildable_init (GtkBuildableIface *iface); static void gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_tree_view_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_tree_view_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); + static gboolean scroll_row_timeout (gpointer data); static void add_scroll_timeout (GtkTreeView *tree_view); @@ -15733,9 +15740,17 @@ gtk_tree_view_get_minimum_size (GtkWidget *widget, } static void -gtk_tree_view_extended_layout_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimal_size, - GtkRequisition *desired_size) +gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_tree_view_get_desired_width; + iface->get_desired_height = gtk_tree_view_get_desired_height; +} + +static void +gtk_tree_view_get_desired_size (GtkExtendedLayout *layout, + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { GtkTreeView *tree_view; gint natural_width = 0; @@ -15746,32 +15761,49 @@ gtk_tree_view_extended_layout_get_desired_size (GtkExtendedLayout *layout, gtk_tree_view_get_minimum_size (GTK_WIDGET (layout), &requisition); - for (column_iter = tree_view->priv->columns; column_iter; column_iter = column_iter->next) + if (orientation == GTK_ORIENTATION_HORIZONTAL) { - GtkTreeViewColumn *column = column_iter->data; + for (column_iter = tree_view->priv->columns; column_iter; column_iter = column_iter->next) + { + GtkTreeViewColumn *column = column_iter->data; + + if (!column->visible) + continue; + + natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column); + } - if (!column->visible) - continue; + if (minimum_size) + *minimum_size = requisition.width; - natural_width += gtk_tree_view_get_real_natural_width_from_column (tree_view, column); + if (natural_size) + *natural_size = MAX (requisition.width, natural_width); } - - if (minimal_size) - *minimal_size = requisition; - - if (desired_size) + else { - desired_size->height = requisition.height; - desired_size->width = MAX (requisition.width, natural_width); + if (minimum_size) + *minimum_size = requisition.height; + + if (natural_size) + *natural_size = requisition.height; } } static void -gtk_tree_view_extended_layout_init (GtkExtendedLayoutIface *iface) +gtk_tree_view_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { - iface->get_desired_size = gtk_tree_view_extended_layout_get_desired_size; + gtk_tree_view_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); } +static void +gtk_tree_view_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_tree_view_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); +} #define __GTK_TREE_VIEW_C__ #include "gtkaliasdef.c" diff --git a/gtk/gtktreeviewcolumn.c b/gtk/gtktreeviewcolumn.c index 8597643654..9f3f25382d 100644 --- a/gtk/gtktreeviewcolumn.c +++ b/gtk/gtktreeviewcolumn.c @@ -2644,9 +2644,15 @@ gtk_tree_view_column_cell_get_real_size (GtkTreeViewColumn *tree_column, nat_req.width += tree_column->spacing; } - gtk_extended_cell_get_desired_size (GTK_EXTENDED_CELL (info->cell), - tree_column->tree_view, - &min_req, &nat_req); + /* XXX TODO: Cell renderers are not really doing height-for-width yet. + */ + gtk_extended_cell_get_desired_width (GTK_EXTENDED_CELL (info->cell), + tree_column->tree_view, + &min_req.width, &nat_req.width); + gtk_extended_cell_get_height_for_width (GTK_EXTENDED_CELL (info->cell), + tree_column->tree_view, + nat_req.width, + &min_req.height, &nat_req.height); min_req.width += focus_line_width * 2; min_req.height += focus_line_width * 2; diff --git a/gtk/gtkviewport.c b/gtk/gtkviewport.c index 404af32641..103a8572f6 100644 --- a/gtk/gtkviewport.c +++ b/gtk/gtkviewport.c @@ -69,6 +69,13 @@ static void gtk_viewport_style_set (GtkWidget *widget, GtkStyle *previous_style); static void gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_viewport_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_viewport_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); + G_DEFINE_TYPE_WITH_CODE (GtkViewport, gtk_viewport, GTK_TYPE_BIN, G_IMPLEMENT_INTERFACE (GTK_TYPE_EXTENDED_LAYOUT, @@ -829,44 +836,67 @@ gtk_viewport_style_set (GtkWidget *widget, } } + +static void +gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface) +{ + iface->get_desired_width = gtk_viewport_get_desired_width; + iface->get_desired_height = gtk_viewport_get_desired_height; +} + static void gtk_viewport_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) + GtkOrientation orientation, + gint *minimum_size, + gint *natural_size) { - GtkWidget *child; - GtkRequisition child_min, child_nat; + GtkWidget *child; + gint child_min, child_nat; + gint minimum, natural; child = gtk_bin_get_child (GTK_BIN (layout)); - minimum_size->width = GTK_CONTAINER (layout)->border_width; - minimum_size->height = GTK_CONTAINER (layout)->border_width; - natural_size->width = GTK_CONTAINER (layout)->border_width; - natural_size->height = GTK_CONTAINER (layout)->border_width; + /* XXX This should probably be (border_width * 2); but GTK+ has + * been doing this with a single border for a while now... + */ + minimum = GTK_CONTAINER (layout)->border_width; if (GTK_VIEWPORT (layout)->shadow_type != GTK_SHADOW_NONE) { - minimum_size->width += 2 * GTK_WIDGET (layout)->style->xthickness; - minimum_size->height += 2 * GTK_WIDGET (layout)->style->ythickness; - natural_size->width += 2 * GTK_WIDGET (layout)->style->xthickness; - natural_size->height += 2 * GTK_WIDGET (layout)->style->ythickness; + if (orientation == GTK_ORIENTATION_HORIZONTAL) + minimum += 2 * GTK_WIDGET (layout)->style->xthickness; + else + minimum += 2 * GTK_WIDGET (layout)->style->ythickness; } + natural = minimum; + if (child && gtk_widget_get_visible (child)) { - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat); + if (orientation == GTK_ORIENTATION_HORIZONTAL) + gtk_extended_layout_get_desired_width (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat); + else + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (child), &child_min, &child_nat); - minimum_size->width += child_min.width; - minimum_size->height += child_min.height; - natural_size->width += child_nat.width; - natural_size->height += child_nat.height; + minimum += child_min; + natural += child_nat; } } static void -gtk_viewport_extended_layout_init (GtkExtendedLayoutIface *iface) +gtk_viewport_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + gtk_viewport_get_desired_size (layout, GTK_ORIENTATION_HORIZONTAL, minimum_size, natural_size); +} + +static void +gtk_viewport_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { - iface->get_desired_size = gtk_viewport_get_desired_size; + gtk_viewport_get_desired_size (layout, GTK_ORIENTATION_VERTICAL, minimum_size, natural_size); } #define __GTK_VIEWPORT_C__ diff --git a/gtk/gtkwidget.c b/gtk/gtkwidget.c index 4254516c3c..a72ad6a566 100644 --- a/gtk/gtkwidget.c +++ b/gtk/gtkwidget.c @@ -344,10 +344,13 @@ static void gtk_widget_buildable_custom_finished (GtkBuildable static void gtk_widget_buildable_parser_finished (GtkBuildable *buildable, GtkBuilder *builder); -static void gtk_widget_layout_interface_init (GtkExtendedLayoutIface *iface); -static void gtk_widget_real_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size); +static void gtk_widget_extended_layout_init (GtkExtendedLayoutIface *iface); +static void gtk_widget_real_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); +static void gtk_widget_real_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size); static void gtk_widget_queue_tooltip_query (GtkWidget *widget); @@ -426,7 +429,7 @@ gtk_widget_get_type (void) const GInterfaceInfo layout_info = { - (GInterfaceInitFunc) gtk_widget_layout_interface_init, + (GInterfaceInitFunc) gtk_widget_extended_layout_init, (GInterfaceFinalizeFunc) NULL, NULL /* interface data */ }; @@ -2849,6 +2852,8 @@ gtk_widget_init (GtkWidget *widget) GTK_PRIVATE_SET_FLAG (widget, GTK_REDRAW_ON_ALLOC); GTK_PRIVATE_SET_FLAG (widget, GTK_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_WIDTH_REQUEST_NEEDED); + GTK_PRIVATE_SET_FLAG (widget, GTK_HEIGHT_REQUEST_NEEDED); GTK_PRIVATE_SET_FLAG (widget, GTK_ALLOC_NEEDED); widget->style = gtk_widget_get_default_style (); @@ -3889,7 +3894,7 @@ gtk_widget_size_request (GtkWidget *widget, "to widget->requisition. gtk_widget_set_usize() may not work properly."); #endif /* G_ENABLE_DEBUG */ - _gtk_size_group_compute_desired_size (widget, requisition, NULL); + gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (widget), requisition, NULL); } /** @@ -9277,12 +9282,16 @@ _gtk_widget_get_aux_info (GtkWidget *widget, aux_info->width = -1; aux_info->height = -1; + aux_info->cached_width_age = 1; + aux_info->cached_height_age = 1; + g_object_set_qdata (G_OBJECT (widget), quark_aux_info, aux_info); } return aux_info; } + /***************************************** * gtk_widget_aux_info_destroy: * @@ -10719,18 +10728,33 @@ gtk_widget_buildable_custom_finished (GtkBuildable *buildable, * GtkExtendedLayout implementation */ static void -gtk_widget_real_get_desired_size (GtkExtendedLayout *layout, - GtkRequisition *minimum_size, - GtkRequisition *natural_size) +gtk_widget_real_get_desired_width (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) { /* Set the initial values so that unimplemented classes will fall back * on the "size-request" collected values (see gtksizegroup.c:do_size_request()). */ if (minimum_size) - memset (minimum_size, 0x0, sizeof (GtkRequisition)); + *minimum_size = GTK_WIDGET (layout)->requisition.width; if (natural_size) - memset (natural_size, 0x0, sizeof (GtkRequisition)); + *natural_size = GTK_WIDGET (layout)->requisition.width; +} + +static void +gtk_widget_real_get_desired_height (GtkExtendedLayout *layout, + gint *minimum_size, + gint *natural_size) +{ + /* Set the initial values so that unimplemented classes will fall back + * on the "size-request" collected values (see gtksizegroup.c:do_size_request()). + */ + if (minimum_size) + *minimum_size = GTK_WIDGET (layout)->requisition.height; + + if (natural_size) + *natural_size = GTK_WIDGET (layout)->requisition.height; } static void @@ -10739,23 +10763,7 @@ gtk_widget_real_get_height_for_width (GtkExtendedLayout *layout, gint *minimum_height, gint *natural_height) { - GtkRequisition minimum_size; - GtkRequisition natural_size; - - g_return_if_fail (GTK_IS_WIDGET (layout)); - -#if 0 - TODO: integrate height-for-width with size-groups -#else - gtk_extended_layout_get_desired_size (layout, - minimum_height ? &minimum_size : NULL, - natural_height ? &natural_size : NULL); - - if (minimum_height) - *minimum_height = minimum_size.height; - if (natural_height) - *natural_height = natural_size.height; -#endif + gtk_extended_layout_get_desired_height (layout, minimum_height, natural_height); } static void @@ -10763,30 +10771,15 @@ gtk_widget_real_get_width_for_height (GtkExtendedLayout *layout, gint height, gint *minimum_width, gint *natural_width) -{ - GtkRequisition minimum_size; - GtkRequisition natural_size; - - g_return_if_fail (GTK_IS_WIDGET (layout)); - -#if 0 - TODO: integrate width-for-height with size-groups -#else - gtk_extended_layout_get_desired_size (layout, - minimum_width ? &minimum_size : NULL, - natural_width ? &natural_size : NULL); - - if (minimum_width) - *minimum_width = minimum_size.width; - if (natural_width) - *natural_width = natural_size.width; -#endif +{ + gtk_extended_layout_get_desired_width (layout, minimum_width, natural_width); } static void -gtk_widget_layout_interface_init (GtkExtendedLayoutIface *iface) +gtk_widget_extended_layout_init (GtkExtendedLayoutIface *iface) { - iface->get_desired_size = gtk_widget_real_get_desired_size; + iface->get_desired_width = gtk_widget_real_get_desired_width; + iface->get_desired_height = gtk_widget_real_get_desired_height; iface->get_width_for_height = gtk_widget_real_get_width_for_height; iface->get_height_for_width = gtk_widget_real_get_height_for_width; } diff --git a/gtk/gtkwidget.h b/gtk/gtkwidget.h index fbc662de95..92c2b8023e 100644 --- a/gtk/gtkwidget.h +++ b/gtk/gtkwidget.h @@ -459,17 +459,22 @@ typedef enum #define GTK_TYPE_REQUISITION (gtk_requisition_get_type ()) +/* Size of the width-for-height/height-for-width caches */ +#define GTK_N_CACHED_SIZES 3 + /* forward declaration to avoid excessive includes (and concurrent includes) */ typedef struct _GtkRequisition GtkRequisition; typedef struct _GtkSelectionData GtkSelectionData; typedef struct _GtkWidgetClass GtkWidgetClass; typedef struct _GtkWidgetAuxInfo GtkWidgetAuxInfo; +typedef struct _GtkDesiredSize GtkDesiredSize; typedef struct _GtkWidgetShapeInfo GtkWidgetShapeInfo; typedef struct _GtkClipboard GtkClipboard; typedef struct _GtkTooltip GtkTooltip; typedef struct _GtkWindow GtkWindow; + /** * GtkAllocation: * @x: the X position of the widget's area relative to its parents allocation. @@ -799,6 +804,14 @@ struct _GtkWidgetClass void (*_gtk_reserved7) (void); }; +struct _GtkDesiredSize +{ + guint age; + gint for_size; + gint minimum_size; + gint natural_size; +}; + struct _GtkWidgetAuxInfo { gint x; @@ -809,7 +822,10 @@ struct _GtkWidgetAuxInfo guint x_set : 1; guint y_set : 1; - GtkRequisition natural_size; + GtkDesiredSize desired_widths[GTK_N_CACHED_SIZES]; + GtkDesiredSize desired_heights[GTK_N_CACHED_SIZES]; + guint cached_width_age; + guint cached_height_age; }; struct _GtkWidgetShapeInfo diff --git a/gtk/gtkwindow.c b/gtk/gtkwindow.c index 5d351cb408..eea412e93f 100644 --- a/gtk/gtkwindow.c +++ b/gtk/gtkwindow.c @@ -4949,43 +4949,18 @@ gtk_window_size_request (GtkWidget *widget, if (bin->child && gtk_widget_get_visible (bin->child)) { - GtkRequisition child_requisition, child_natural; - gint wfh, hfw; + gint width, height; + /* XXX Use the minimum width for the natural height; even if its an hbox. + * + * This doesnt need to be here; naturally it will use the preference of the child + * except for testing purposes its more interesting this way. + */ + gtk_extended_layout_get_desired_height (GTK_EXTENDED_LAYOUT (bin->child), NULL, &height); + gtk_extended_layout_get_width_for_height (GTK_EXTENDED_LAYOUT (bin->child), height, &width, NULL); - gtk_extended_layout_get_desired_size (GTK_EXTENDED_LAYOUT (bin->child), - &child_requisition, - &child_natural); - - /* TODO: Change wrapping label requisitions to desired a user intended wrap length, - * and make the minimum size out the minimum height for the natural-width, instead of - * the minimum height for the minimum width, which is backwards */ - if (window->type != GTK_WINDOW_POPUP) - { - if (gtk_extended_layout_is_height_for_width (GTK_EXTENDED_LAYOUT (bin->child))) - { - gtk_extended_layout_get_height_for_width (GTK_EXTENDED_LAYOUT (bin->child), - child_natural.width, - &hfw, NULL); - - requisition->width += child_requisition.height; - requisition->height += hfw; - } - else - { - gtk_extended_layout_get_width_for_height (GTK_EXTENDED_LAYOUT (bin->child), - child_natural.height, - &wfh, NULL); - - requisition->width += wfh; - requisition->height += child_requisition.height; - } - } - else - { - requisition->width += child_requisition.width; - requisition->height += child_requisition.height; - } + requisition->width += width; + requisition->height += height; } } -- 2.30.2